Wie entkomme ich einem einfachen Anführungszeichen in sed?

88

Wie entkomme ich einem einzelnen Anführungszeichen in einem sed-Ausdruck, der bereits von Anführungszeichen umgeben ist?

Beispielsweise:

sed 's/ones/one's/' <<< 'ones thing'
Thomas Bratt
quelle
Die kurze Antwort lautet " Sie können das nicht tun " - die vorgestellten Problemumgehungen funktionieren alle gut.
Glenn Jackman

Antworten:

146

Zitat - sedCodes mit doppelten Anführungszeichen:

    $ sed "s/ones/one's/"<<<"ones thing"   
    one's thing

Ich mag es nicht, Codes mit Hunderten von Backslashes zu entkommen - tut meinen Augen weh. Normalerweise mache ich das so:

    $ sed 's/ones/one\x27s/'<<<"ones thing"
    one's thing
Kent
quelle
7
Dies scheint aus sed -iirgendeinem Grund nicht zu funktionieren ?
T. Rex
36

Ein Trick besteht darin, die Verkettung benachbarter Zeichenfolgen mit der Shell-Zeichenfolge zu verwenden und das eingebettete Anführungszeichen mithilfe der Shell-Escapezeichenfolge zu umgehen:

sed 's/ones/two'\''s/' <<< 'ones thing'

two's thing

Der sed-Ausdruck enthält 3 Zeichenfolgen, die die Schale dann zusammennäht:

sed 's/ones/two'

\'

's/'

Hoffe das hilft jemand anderem!

Thomas Bratt
quelle
vielleicht eine einfachere Variante: sed 's / one / two' s / '<<<' one thing '
Gregory
@gregory: sed 's/ones/two''s/' <<< 'ones thing'Nein, das gibt aus twos thing. Es fehlt das 'in der Ausgabe. Sie müssen es wie in dieser Antwort beschrieben tun.
wisbucky
@wisbucky Mit der Version von sed, die ich (FreeBSD / macOS) auf zsh verwende, wird definitiv "two's thing" ausgegeben.
Gregory
große Hilfe Mann, indem Sie mich wissen lassen, Muschel dann zusammennäht.
Prateek Gupta
6

Der beste Weg ist zu verwenden $'some string with \' quotes \''

z.B:

sed $'s/ones/two\'s/' <<< 'ones thing'
John C.
quelle
3
Der C-Stil $'string'ist Bash-spezifisch und daher nicht auf die POSIX-Shell portierbar.
Tripleee
Es ist nicht bashspezifisch. Es ist auch in kshund verfügbar zsh, aber ja, es ist eine Erweiterung von POSIX, was in Ordnung ist, wenn Sie kein portables Skript schreiben. Der einzige Nachteil ist, dass Sie sich auch anderen Backslashes entziehen müssen, die Sie verwenden.
Danny
6

Verwenden Sie einfach doppelte Anführungszeichen außerhalb des Befehls sed.

$ sed "s/ones/one's/" <<< 'ones thing'
one's thing

Es funktioniert auch mit Dateien.

$ echo 'ones thing' > testfile
$ sed -i "s/ones/one's/" testfile
$ cat testfile
one's thing

Wenn Sie einfache und doppelte Anführungszeichen in der Zeichenfolge haben, ist dies auch in Ordnung. Entfliehen Sie einfach den doppelten Anführungszeichen.

Diese Datei enthält beispielsweise eine Zeichenfolge mit einfachen und doppelten Anführungszeichen. Ich werde sed verwenden, um ein einfaches Anführungszeichen hinzuzufügen und einige doppelte Anführungszeichen zu entfernen.

$ cat testfile
"it's more than ones thing"
$ sed -i "s/\"it's more than ones thing\"/it's more than one's thing/" testfile 
$ cat testfile 
it's more than one's thing
Stef Forrester
quelle
Vielen Dank! Ich liebe Regex, liebe Sed und jetzt liebe ich dich <3
Gabriel A. Zorrilla
3

Dies ist eine Art absurd , aber ich konnte nicht \'in sed 's/ones/one\'s/'zu arbeiten. Ich habe nachgeschlagen, um ein Shell-Skript import 'hammerjs';zu src/main.tserstellen, das mit Angular automatisch zu meiner Datei hinzugefügt wird .

Was ich zur Arbeit gebracht habe, ist Folgendes:

apost=\'
sed -i '' '/environments/a\
import '$apost'hammerjs'$apost';' src/main.ts

Für das obige Beispiel wäre es also:

apost=\'
sed 's/ones/one'$apost's/'

Ich habe keine Ahnung, warum ich nicht \'alleine arbeiten würde, aber da ist es.

Ambrown
quelle
0

Ich weiß, dass dies wie ein Polizist klingen wird, aber ich könnte mich nie zum Arbeiten bringen, wenn die Zeichenfolge sowohl einfache als auch doppelte Anführungszeichen enthält. Um Neulingen wie mir zu helfen, die Probleme haben, besteht eine Möglichkeit darin, die Zeichenfolge aufzuteilen. Ich musste Code in über 100 index.hmtl-Dateien ersetzen. Die Zeichenfolgen hatten sowohl einfache als auch doppelte Anführungszeichen, also habe ich die Zeichenfolge einfach aufgeteilt und den ersten Block durch <!--und den zweiten Block durch ersetzt -->. Es hat meine index.html-Dateien durcheinander gebracht, aber es hat funktioniert.

mcmacerson
quelle
0

Einige Escapes auf AppleMacOSX-Terminals schlagen fehl:

sed 's|ones|one'$(echo -e "\x27")'s|1' <<<'ones thing'

PaSe
quelle
0

Verwenden Sie einen alternativen String-Separator wie ":", um Verwechslungen mit verschiedenen Schrägstrichen zu vermeiden

sed "s:ones:one's:" <<< 'ones thing'

oder wenn Sie das einfache Anführungszeichen hervorheben möchten

sed "s:ones:one\'s:" <<< 'ones thing'

beide kehren zurück

one's thing
Gehirnelektronik
quelle