Wie entkomme ich doppelten und einfachen Anführungszeichen in sed?

76

Soweit ich feststellen kann, wird bei Verwendung von einfachen Anführungszeichen alles im Inneren als wörtlich betrachtet. Ich möchte das für meine Ersetzung. Ich möchte aber auch eine Zeichenfolge mit einfachen oder doppelten Anführungszeichen finden.

Zum Beispiel,

sed -i 's/"http://www.fubar.com"/URL_FUBAR/g'

Ich möchte "http://www.fubar.com" durch URL_FUBAR ersetzen. Wie soll sed meine // oder meine doppelten Anführungszeichen erkennen?

Vielen Dank für jede Hilfe!

EDIT: Könnte ich verwenden s/\"http\:\/\/www\.fubar\.\com\"/URL_FUBAR/g?

Entkommt \ tatsächlich Zeichen in den einfachen Anführungszeichen?

KRB
quelle

Antworten:

104

Mit dem s///Befehl in sedkönnen Sie andere Zeichen anstelle des /Trennzeichens wie in verwenden

sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'

oder

sed 's,"http://www\.fubar\.com",URL_FUBAR,g'

Die doppelten Anführungszeichen sind kein Problem. Um übereinstimmende einfache Anführungszeichen zu erhalten, wechseln Sie die beiden Arten von Anführungszeichen. Beachten Sie, dass eine Zeichenfolge in einfachen Anführungszeichen möglicherweise keine einfachen Anführungszeichen enthält (nicht einmal maskierte Anführungszeichen).

Die Punkte müssen maskiert werden, wenn sedsie als wörtliche Punkte interpretiert werden sollen und nicht als Muster für reguläre Ausdrücke, .das einem Zeichen entspricht.

Kusalananda
quelle
tolle antwort dood, ich habe nur eine kurze frage. Wie würde ich einfache Anführungszeichen anstelle meiner Doppel machen? Ich habe Fälle in meinem Code, in denen es entweder einfach oder doppelt ist. Ich kann diesen Befehl nur zweimal ausführen, aber wie lautet die Syntax, um ein einfaches Anführungszeichen zu umgehen?
KRB
Das Escapezeichen für einfache Anführungszeichen hat bei mir nicht funktioniert (Bash auf dem Mac), aber die Verwendung anderer Anführungszeichen zum Umbrechen des Befehls als das zu ersetzende Anführungszeichen hat funktioniert. zB: sed 's/"/bla/g'ersetzen "durch blaoder sed "s/'/bla/g" to replace '`mitbla
rrr
1
@rrr Eine Zeichenfolge in einfachen Anführungszeichen darf kein eingebettetes einfaches Anführungszeichen enthalten. Das Ändern der äußeren Anführungszeichen (und das Entkommen von Sonderzeichen, die die Shell jetzt möglicherweise interpretieren möchte) ist eine Möglichkeit, dies zu lösen. Eine andere Möglichkeit besteht darin, aus der Zeichenfolge in einfachen Anführungszeichen auszubrechen und die Zeichenfolge mit "'"(einem einfachen Anführungszeichen in doppelten Anführungszeichen) zu verketten, bevor Sie mit dem Rest der Zeichenfolge in einfachen Anführungszeichen fortfahren, wie in 'you'"'"'d better do that'.
Kusalananda
28

Informationen zum einfachen Anführungszeichen finden Sie im folgenden Code, mit dem die Zeichenfolge ersetzt wird let'sdurch let us:

Befehl:

echo "hello, let's go"|sed 's/let'"'"'s/let us/g'

Ergebnis:

Hallo, lass uns gehen

Tony Duan
quelle
13

Es ist schwer, einem einfachen Anführungszeichen in einfachen Anführungszeichen zu entkommen. Versuche dies:

sed "s@['\"]http://www.\([^.]\+).com['\"]@URL_\U\1@g" 

Beispiel:

$ sed "s@['\"]http://www.\([^.]\+\).com['\"]@URL_\U\1@g" <<END
this is "http://www.fubar.com" and 'http://www.example.com' here
END

produziert

this is URL_FUBAR and URL_EXAMPLE here
Glenn Jackman
quelle
13

Mein Problem war, dass ich das ""Äußere des Ausdrucks haben musste, da ich eine dynamische Variable innerhalb des sed-Ausdrucks selbst habe. Die eigentliche Lösung ist also die von Lenn Jackman, durch die Sie das "Innere des Sed Regex ersetzen [\"].

Meine komplette Bash ist also:

RELEASE_VERSION="0.6.6"

sed -i -e "s#value=[\"]trunk[\"]#value=\"tags/$RELEASE_VERSION\"#g" myfile.xml

Hier ist:

# ist der sed Separator

[\"] = "in Regex

value = \"tags/$RELEASE_VERSION\" = meine Ersatzzeichenfolge, wichtig, dass sie nur \"die Anführungszeichen enthält

Denis
quelle
1

Das Entkommen eines doppelten Anführungszeichens kann in sed unbedingt erforderlich sein: Zum Beispiel, wenn Sie doppelte Anführungszeichen im gesamten sed-Ausdruck verwenden (wie Sie es tun müssen, wenn Sie eine Shell-Variable verwenden möchten).

Hier ist ein Beispiel, das die Flucht in sed berührt, aber auch einige andere Zitierprobleme in bash erfasst:

# cat inventory
PURCHASED="2014-09-01"
SITE="Atlanta"
LOCATION="Room 154"

Angenommen, Sie wollten den Raum mithilfe eines sed-Skripts ändern, das Sie immer wieder verwenden können, sodass Sie die Eingabe wie folgt variieren können:

# i="Room 101" (these quotes are there so the variable can contains spaces)

Dieses Skript fügt die gesamte Zeile hinzu, wenn sie nicht vorhanden ist, oder ersetzt einfach (mit sed) die vorhandene Zeile durch den Text plus den Wert von $ i.

if grep -q LOCATION inventory; then 
## The sed expression is double quoted to allow for variable expansion; 
## the literal quotes are both escaped with \ 
    sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory
## Note the three layers of quotes to get echo to expand the variable
## AND insert the literal quotes
else 
    echo LOCATION='"'$i'"' >> inventory
fi

PS Ich habe das obige Skript in mehreren Zeilen geschrieben, um die Kommentare analysierbar zu machen, aber ich verwende es als Einzeiler in der Befehlszeile, die so aussieht:

i="your location"; if grep -q LOCATION inventory; then sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory; else echo LOCATION='"'$i'"' >> inventory; fi
starry_eyed_sysadmin
quelle
1

Nebenbei: sed-Ausdrücke, die BASH-Variablen enthalten, müssen doppelt ( ") in Anführungszeichen gesetzt werden, damit die Variable korrekt interpretiert wird.

Wenn Sie auch Ihre $ BASH-Variable in doppelte Anführungszeichen setzen (empfohlene Vorgehensweise)

... dann können Sie den variablen doppelten Anführungszeichen wie gezeigt entkommen:

sed -i "s/foo/bar ""$VARIABLE""/g" <file>

Dh, ersetzen Sie das $ VARIABLE-assoziierte "mit "".

(Einfach -scaping "$VAR"als \"$VAR\"Ergebnis in einer "-quotierten Ausgabezeichenfolge.)


Beispiele

$ VAR='apples and bananas'
$ echo $VAR
apples and bananas

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' $VAR
I like apples!
I like and!
I like bananas!

$ printf 'I like %s!\n' "$VAR"
I like apples and bananas!

Hier wird $ VAR vor der "Weiterleitung an sed angegeben (sed ist entweder '- oder "angegeben):

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/"$VAR"/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/""$VAR""/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed "s/$VAR/cherries/g"
I like cherries!

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!

Vergleichen Sie das mit:

$ printf 'I like %s!\n' $VAR | sed "s/$VAR/cherries/g"
I like apples!
I like and!
I like bananas!


$ printf 'I like %s!\n' $VAR | sed "s/""$VAR""/cherries/g"
I like apples!
I like and!
I like bananas!

... und so weiter ...

Fazit

Meine Empfehlung lautet standardmäßig:

  • "-quote BASH-Variablen ( "$VAR")
  • "-quote wiederum diese Variablen ( ""$VAR""), wenn sie in einem sed-Ausdruck verwendet werden (der selbst "-quoted, nicht '-quoted sein muss)
$ VAR='apples and bananas'

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!

Victoria Stuart
quelle
0
Prompt% cat t1
This is "Unix"
This is "Unix sed"
Prompt% sed -i 's/\"Unix\"/\"Linux\"/g' t1
Prompt% sed -i 's/\"Unix sed\"/\"Linux SED\"/g' t1
Prompt% cat t1
This is "Linux"
This is "Linux SED"
Prompt%
SachinH
quelle
Verwenden Sie einfach (Schrägstrich) vor "(doppelte Anführungszeichen) .. und verwenden Sie die Option -i
SachinH
1
Während dieser Code - Schnipsel zu begrüßen ist, und etwas Hilfe bieten kann, würde es erheblich verbessert , wenn es eine Erklärung enthalten von , wie es um die Frage anspricht. Ohne das hat Ihre Antwort einen viel geringeren pädagogischen Wert - denken Sie daran, dass Sie die Frage in Zukunft für die Leser beantworten, nicht nur für die Person, die jetzt fragt! Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, und geben Sie an, welche Einschränkungen und Annahmen gelten.
Toby Speight
0

Sie können% verwenden

sed -i "s%http://www.fubar.com%URL_FUBAR%g"
Andrey
quelle
-4

Sie müssen das Zeichen "zum Escape" verwenden (\ das folgende Zeichen maskieren)

sed -i 's/\"http://www.fubar.com\"/URL_FUBAR/g'
Guilhem Hoffmann
quelle
-7

Kann das "\" Zeichen sein, versuchen Sie dieses:

sed 's/\"http:\/\/www.fubar.com\"/URL_FUBAR/g'
Giuseppe La Rosa
quelle
4
Eine wilde Vermutung vorzuschlagen ist keine Lösung. Sie können solche Vermutungen stattdessen in Kommentaren hinzufügen - oder noch besser - probieren Sie es zuerst aus
SeriousM