Der normale Weg, dies zu tun, ist die Verwendung von Schrägstrichen, aber das kann umständlich werden, wenn Sie etwas suchen und durch Schrägstriche ersetzen. Dies ist hier nicht der Fall, und obwohl es vollkommen in Ordnung ist, verwirrt es zukünftige Betreuer wie Sie.
Thorbjørn Ravn Andersen
2
… Und führt sie dazu, auf seddiese Weise etwas Neues zu lernen ! :)
Nachtisch
Antworten:
15
In sed werden Ersatzbefehle normalerweise als geschrieben s/pattern/replacement/options. Es ist jedoch nicht erforderlich, es zu verwenden /- Sie können andere Zeichen verwenden, wenn es zweckmäßig ist, also könnte es s@pattern@replacement@optionsoder sein s:foo:bar:g. s@+@ @gist wie s/+/ /g- alle +durch Leerzeichen ersetzen . Ersetzt in ähnlicher Weise s@%@\\x@galle %durch \x(ein einzelner Backslash ist ein Escape-Zeichen in sed, Sie benötigen also zwei, um einen tatsächlichen Backslash zu erhalten).
Eine Zeichenfolge wie foo+%2Fbarwird dann foo \x2Fbar. printf "%b"erweitert die Backslash-Escape-Sequenzen wie \x2F(das ASCII-Zeichen, dessen hexadezimaler Wert 2F ist /), um Ihnen schließlich zu geben foo /bar.
Sie können mehr gewöhnt werden sie mit zu sehen , /anstatt @als Separator, die leicht hier da getan haben , ohne Komplikation könnte , /erscheint in keiner der Suchmuster noch eine der Ersetzungstexte. Dieser Befehl ist äquivalent:
sed 's/+/ /g;s/%/\\x/g'
Wie /, @ist eine ganz gute Interpunktionszeichen für sed.
In jeder Eingabezeile:
s@+@ @g( s/+/ /g) ersetzt ( s) Vorkommen von +durch ein Leerzeichen. Dies betrifft alle +es in einer Zeile ( g), nicht nur die erste.
; beendet die Aktion ("Befehl") und ermöglicht es Ihnen, eine andere im selben "Skript" anzugeben.
s@%@\\x@g( s/%/\\x/g) ersetzt ( s) Vorkommen von %mit \x. Nach wie vor wirkt es auf alle und nicht nur auf die erste jeder Zeile ( g).
In \\xder \\stellt nur eine dar, \weil \sie eine besondere Bedeutung hat sed. Seine besondere Bedeutung ist eigentlich das Zeichen, mit dem Sie die besondere Bedeutung eines anderen Zeichens entfernen, das danach kommt und das sonst eine besondere Bedeutung hätte. Also muss es als entkommen \\.
Schauen wir uns nun den xargsBefehl an, dessen Zweck die Ausführung ist printf.
xargserstellt Befehlszeilen. Wenn Sie laufen , wo ein oder mehr Wort, läuft mit zusätzlichen Befehlszeilenargumente von seinem Eingang zu lesen. In diesem Fall ist die Eingabe in die Ausgabe von aufgrund der Pipe ( ). Normalerweise interpretiert jedes Leerzeichen in seiner Eingabe so, dass der Text vor und nach dem Schreiben separate Argumente darstellt. Mit dieser Option werden jedoch Argumente beim Auftreten des Nullzeichens aufgeteilt .xargs command...command...xargscommand...xargssed|xargs-0
Bei der beabsichtigten Verwendung Ihres Befehls wird kein Nullzeichen angezeigt und xargsnur printf %bmit einem zusätzlichen Befehlszeilenargument ausgeführt, der Ausgabe des sedBefehls. Während also nicht gleichwertig in der Regel in diesem Fall die gesamte Pipeline könnte statt wie diese verwenden geschrieben wurde Befehl Substitution statt xargs:
printf '%b\n'"$(sed 's/+/ /g;s/%/\\x/g')"
Was printfhier zu tun ist, wie Muru sagt,%b verbraucht und druckt der Formatbezeichner ein Argument (wie %s), bewirkt jedoch, dass Backslash-Escapezeichen - wie sie vom sedBefehl auf der linken Seite der Pipe generiert wurden - übersetzt werden in die Zeichen, die sie darstellen .
Angenommen, ich führe diesen Befehl aus und übergebe ihn http://foldoc.org/debugging%20by%20printfals Eingabe. Ich bekomme http://foldoc.org/debugging by printfals Ausgabe, weil die %20Sequenzen in Leerzeichen übersetzt werden.
Das ist das Schöne daran sed, es wendet seine Paradigmen auf sich selbst an ... Nach dem Befehl (wie soder troder nichts) wird das nächste Zeichen als Trennzeichen betrachtet.
Sie sollten mit Bedacht wählen, um Interferenzen mit der Shell und dem Befehl selbst zu vermeiden und die Sache lesbar zu halten, aber es ist absolut gültig, etwas so Schreckliches zu schreiben wie:
echo 'arrival' | sed srarbrg
... und brrivblals Ergebnis erhalten, was Sie erwarten. Sie können Spaß daran haben, es wirklich kryptisch zu machen, wie in:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
Die übliche Verwendung besteht darin, den Schrägstrich als Trennzeichen zu verwenden. Wenn Ihr Ausdruck jedoch das Trennzeichen enthält, ist es einfacher, die Absicht zu erfassen. Ihr Trennzeichen kann alles im ASCII8-Bereich sein (Multibyte-Trennzeichen, die beispielsweise £einen Fehler hervorrufen).
Denken Sie daran, das Ziel ist es, die Dinge einfacher und nicht kryptischer zu machen.
Mit der kryptischen Idee ausgeführt, ist dies ein gültiger sed-Befehl, obwohl er nichts Nützliches sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
bewirkt
Nett! Ja, Sie können sedBefehle auch als Denksportaufgaben verwenden. Wie geekig ist das?
sed
diese Weise etwas Neues zu lernen ! :)Antworten:
In sed werden Ersatzbefehle normalerweise als geschrieben
s/pattern/replacement/options
. Es ist jedoch nicht erforderlich, es zu verwenden/
- Sie können andere Zeichen verwenden, wenn es zweckmäßig ist, also könnte ess@pattern@replacement@options
oder seins:foo:bar:g
.s@+@ @g
ist wies/+/ /g
- alle+
durch Leerzeichen ersetzen . Ersetzt in ähnlicher Weises@%@\\x@g
alle%
durch\x
(ein einzelner Backslash ist ein Escape-Zeichen in sed, Sie benötigen also zwei, um einen tatsächlichen Backslash zu erhalten).Eine Zeichenfolge wie
foo+%2Fbar
wird dannfoo \x2Fbar
.printf "%b"
erweitert die Backslash-Escape-Sequenzen wie\x2F
(das ASCII-Zeichen, dessen hexadezimaler Wert 2F ist/
), um Ihnen schließlich zu gebenfoo /bar
.quelle
Der Befehl, nach dem Sie zum Dekodieren von
+
es und%
Sequenzen aus URLs fragen, ist nicht nur einsed
Befehl, sondern eine Pipeline , die Eingaben verarbeitetsed
undxargs
zur weiteren Verarbeitung an diese weiterleitet. Schauen wir uns zuerst densed
Befehl an:Sie können mehr gewöhnt werden sie mit zu sehen ,
/
anstatt@
als Separator, die leicht hier da getan haben , ohne Komplikation könnte ,/
erscheint in keiner der Suchmuster noch eine der Ersetzungstexte. Dieser Befehl ist äquivalent:Wie
/
,@
ist eine ganz gute Interpunktionszeichen fürsed
.In jeder Eingabezeile:
s@+@ @g
(s/+/ /g
) ersetzt (s
) Vorkommen von+
durch ein Leerzeichen. Dies betrifft alle+
es in einer Zeile (g
), nicht nur die erste.;
beendet die Aktion ("Befehl") und ermöglicht es Ihnen, eine andere im selben "Skript" anzugeben.s@%@\\x@g
(s/%/\\x/g
) ersetzt (s
) Vorkommen von%
mit\x
. Nach wie vor wirkt es auf alle und nicht nur auf die erste jeder Zeile (g
).In
\\x
der\\
stellt nur eine dar,\
weil\
sie eine besondere Bedeutung hatsed
. Seine besondere Bedeutung ist eigentlich das Zeichen, mit dem Sie die besondere Bedeutung eines anderen Zeichens entfernen, das danach kommt und das sonst eine besondere Bedeutung hätte. Also muss es als entkommen\\
.Schauen wir uns nun den
xargs
Befehl an, dessen Zweck die Ausführung istprintf
.xargs
erstellt Befehlszeilen. Wenn Sie laufen , wo ein oder mehr Wort, läuft mit zusätzlichen Befehlszeilenargumente von seinem Eingang zu lesen. In diesem Fall ist die Eingabe in die Ausgabe von aufgrund der Pipe ( ). Normalerweise interpretiert jedes Leerzeichen in seiner Eingabe so, dass der Text vor und nach dem Schreiben separate Argumente darstellt. Mit dieser Option werden jedoch Argumente beim Auftreten des Nullzeichens aufgeteilt .xargs command...
command...
xargs
command...
xargs
sed
|
xargs
-0
Bei der beabsichtigten Verwendung Ihres Befehls wird kein Nullzeichen angezeigt und
xargs
nurprintf %b
mit einem zusätzlichen Befehlszeilenargument ausgeführt, der Ausgabe dessed
Befehls. Während also nicht gleichwertig in der Regel in diesem Fall die gesamte Pipeline könnte statt wie diese verwenden geschrieben wurde Befehl Substitution stattxargs
:Was
printf
hier zu tun ist, wie Muru sagt,%b
verbraucht und druckt der Formatbezeichner ein Argument (wie%s
), bewirkt jedoch, dass Backslash-Escapezeichen - wie sie vomsed
Befehl auf der linken Seite der Pipe generiert wurden - übersetzt werden in die Zeichen, die sie darstellen .Angenommen, ich führe diesen Befehl aus und übergebe ihn
http://foldoc.org/debugging%20by%20printf
als Eingabe. Ich bekommehttp://foldoc.org/debugging by printf
als Ausgabe, weil die%20
Sequenzen in Leerzeichen übersetzt werden.quelle
Das ist das Schöne daran
sed
, es wendet seine Paradigmen auf sich selbst an ... Nach dem Befehl (wies
odertr
oder nichts) wird das nächste Zeichen als Trennzeichen betrachtet.Sie sollten mit Bedacht wählen, um Interferenzen mit der Shell und dem Befehl selbst zu vermeiden und die Sache lesbar zu halten, aber es ist absolut gültig, etwas so Schreckliches zu schreiben wie:
... und
brrivbl
als Ergebnis erhalten, was Sie erwarten. Sie können Spaß daran haben, es wirklich kryptisch zu machen, wie in:Die übliche Verwendung besteht darin, den Schrägstrich als Trennzeichen zu verwenden. Wenn Ihr Ausdruck jedoch das Trennzeichen enthält, ist es einfacher, die Absicht zu erfassen. Ihr Trennzeichen kann alles im ASCII8-Bereich sein (Multibyte-Trennzeichen, die beispielsweise
£
einen Fehler hervorrufen).Denken Sie daran, das Ziel ist es, die Dinge einfacher und nicht kryptischer zu machen.
quelle
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sed
Befehle auch als Denksportaufgaben verwenden. Wie geekig ist das?