String-Manipulation mit geschweiften Klammern in Bash

String-Manipulation mit geschweiften Klammern in Bash

Ich habe einen String aus einer Latex-Datei, den ich gerne bearbeiten würde:

\title{This is the title}

Ich möchte "Dies ist der Titel" in einer Variable speichern, schaffe es aber nicht, die Teilstrings mit den geschweiften Klammern zu entfernen, trotz meiner Versuche, diese zu umgehen.

title=`grep -F "\title" file.tex`
title=${title#\}}
title=${title%\{}

Keines davon funktioniert, und das Setzen der geschweiften Klammern in einfache oder doppelte Anführungszeichen funktioniert auch nicht.

Antwort1

Angenommen, dies $titleist die Zeichenfolge \title{This is the title}:

title=${title#*{}
title=${title%\}}

Die {Substitution im ersten Parameter muss nicht maskiert werden (das Maskieren führt jedoch nicht dazu, dass sie nicht funktioniert), aber die }im zweiten muss maskiert werden. Im ersten müssen Sie zusätzlich das Bit in der Zeichenfolge *abgleichen , alternativ können Sie verwenden , um die explizite Zeichenfolge zu löschen .\title${title#\\title{}\title{

Sie scheinen in Ihrem Code das %„und“ #verwechselt zu haben und Sie haben das *in der Ersetzung vergessen, die die Präfixzeichenfolge entfernt.


Vorausgesetzt, kein Titel-String erstreckt sich über mehr als eine Zeile, können Sie alle diese Strings aus einem Dokument mit

sed -n 's/.*\\title{\([^}]*\)}.*/\1/p' file

Dies gleicht (das erste) \title{SOMETHING}in jeder Zeile ab und ersetzt die gesamte Zeile durch die SOMETHINGTeilzeichenfolge. Alle anderen Daten werden verworfen.

Antwort2

Wenn Sie Bash verwenden, können Sie stattdessen dessen Regex-Funktionen nutzen:

title='\title{This is the title}'
[[ $title =~ \{(.*)\} ]] && title=${BASH_REMATCH[1]}
echo "title=$title"

title=This is the title

Vorausgesetzt, Sie müssen dies wirklich in Bash tun. Wenn das Zeug aus einer Datei kommt, sollten Sie Tools verwenden, die besser geeignet sind, Daten aus Dateien zu extrahieren und zu analysieren, wie grep, awk, perl, oder texselbst.

Antwort3

Ich würde nicht versuchen, dies in der Shell zu tun. Analysieren Sie einfach die Ausgabe, grepbevor Sie sie in einer Variablen speichern:

title=$(grep -F '\title' file.tex | sed s'/.*{\(.*\)}/\1/')

oder

title=$(grep -F '\title' file.tex | awk -F'[{}]' '{print $2}')

Oder, wenn Sie GNU grepoder eine andere Implementierung haben, die -ound unterstützt -P, können Sie Folgendes tun:

title=$(grep -oP '\\title\{\K[^}]+' file.tex)

verwandte Informationen