Kann jemand erklären, wie dieser sed
Befehl funktioniert?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sed
diese Weise etwas Neues zu lernen ! :)
Kann jemand erklären, wie dieser sed
Befehl funktioniert?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
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 es s@pattern@replacement@options
oder sein s:foo:bar:g
. s@+@ @g
ist wie s/+/ /g
- alle +
durch Leerzeichen ersetzen . Ersetzt in ähnlicher Weise s@%@\\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 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
.
Der Befehl, nach dem Sie zum Dekodieren von +
es und %
Sequenzen aus URLs fragen, ist nicht nur ein sed
Befehl, sondern eine Pipeline , die Eingaben verarbeitet sed
und xargs
zur weiteren Verarbeitung an diese weiterleitet. Schauen wir uns zuerst den sed
Befehl an:
sed 's@+@ @g;s@%@\\x@g'
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 \\x
der \\
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 xargs
Befehl an, dessen Zweck die Ausführung ist printf
.
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
nur printf %b
mit einem zusätzlichen Befehlszeilenargument ausgeführt, der Ausgabe des sed
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 statt xargs
:
printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
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 vom sed
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 bekomme http://foldoc.org/debugging by printf
als Ausgabe, weil die %20
Sequenzen in Leerzeichen übersetzt werden.
Das ist das Schöne daran sed
, es wendet seine Paradigmen auf sich selbst an ... Nach dem Befehl (wie s
oder tr
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:
echo 'arrival' | sed srarbrg
... und brrivbl
als 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.
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?