Kann jemand erklären, wie dieser sedBefehl funktioniert?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
seddiese Weise etwas Neues zu lernen ! :)
Kann jemand erklären, wie dieser sedBefehl funktioniert?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
seddiese 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@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.
Der Befehl, nach dem Sie zum Dekodieren von +es und %Sequenzen aus URLs fragen, ist nicht nur ein sedBefehl, sondern eine Pipeline , die Eingaben verarbeitet sedund xargszur weiteren Verarbeitung an diese weiterleitet. Schauen wir uns zuerst den sedBefehl 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 \\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.
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sedBefehle auch als Denksportaufgaben verwenden. Wie geekig ist das?