it-swarm.com.de

Wie funktioniert dieser 'sed'-Ersetzungsbefehl mit vielen @ -Zeichen?

Kann jemand erklären, wie dieser Befehl sed funktioniert?

sed '[email protected][email protected] @g;[email protected]%@\\[email protected]' | xargs -0 printf "%b"
8
Raj

In sed werden Ersatzbefehle normalerweise als s/pattern/replacement/options geschrieben. Es ist jedoch nicht erforderlich, / zu verwenden. Sie können auch andere Zeichen verwenden, wenn dies zweckmäßig ist. Es kann sich also um [email protected]@[email protected] oder s:foo:bar:g handeln. [email protected][email protected] @g ist wie s/+/ /g - Ersetzen Sie alle + durch Leerzeichen. In ähnlicher Weise ersetzt [email protected]%@\\[email protected] den gesamten % durch \x (ein einzelner Backslash ist ein Escape-Zeichen in sed, sodass Sie zwei benötigen, um einen tatsächlichen Backslash zu erhalten).

Ein String wie foo+%2Fbar wird dann zu foo \x2Fbar. printf "%b" erweitert die mit einem Backslash versehenen Sequenzen wie \x2F (das ASCII -Zeichen mit dem Hexadezimalwert 2F (/)), um schließlich foo /bar zu erhalten.

15
muru

Der Befehl, nach dem Sie fragen, ob Sie _+_ es und _%_ Sequenzen aus URLs dekodieren möchten ist nicht nur ein Befehl sed, sondern ein Pipeline , der Eingaben verarbeitet mit sed , leitet es dann zur weiteren Verarbeitung an xargs weiter. Schauen wir uns zuerst den Befehl sed an:

_sed '[email protected][email protected] @g;[email protected]%@\\[email protected]'
_

Möglicherweise sind Sie eher daran gewöhnt, es mit _/_ als mit _@_ als Trennzeichen zu sehen, was hier ohne Komplikationen möglich gewesen wäre, da _/_ weder in den Suchmustern noch in den Suchmustern von vorkommt die Ersatztexte. Dieser Befehl ist äquivalent:

_sed 's/+/ /g;s/%/\\x/g'
_

Wie _/_ ist _@_ ein perfektes Interpunktionszeichen für sed.

In jeder Eingabezeile:

  1. _[email protected][email protected] @g_ (_s/+/ /g_) ersetzt (s) Vorkommen von _+_ durch ein Leerzeichen. Dies betrifft alle _+_ in einer Zeile (g), nicht nur die erste.

  2. _;_ beendet die Aktion ("Befehl") und ermöglicht es Ihnen, eine andere im selben "Skript" anzugeben.

  3. _[email protected]%@\\[email protected]_ (_s/%/\\x/g_) ersetzt (s) Vorkommen von _%_ mit _\x_. Nach wie vor wirkt es auf alle und nicht nur auf den ersten jeder Zeile (g).

    In _\\x_ repräsentiert der _\\_ nur einen _\_, da _\_ eine besondere Bedeutung für sed hat. 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. Es muss also als _\\_ maskiert werden.


Schauen wir uns nun den Befehl xargs an, dessen Zweck darin besteht, printf auszuführen.

xargs erstellt Befehlszeilen. Wenn Sie _xargs command..._ ausführen, wobei command... ein oder mehrere Wörter sind, wird xargs ausgeführt command... mit zusätzlichen Kommandozeilen-Argumenten von seiner Eingabe lesen. In diesem Fall ist die Eingabe für xargs aufgrund der Pipe (_|_) die Ausgabe von sed. Normalerweise interpretiert xargs ein beliebiges Leerzeichen in seiner Eingabe so, dass der Text davor und danach separate Argumente darstellt. Mit der Option _-0_ werden die Argumente jedoch beim Auftreten des Nullzeichen aufgeteilt.

Bei der beabsichtigten Verwendung Ihres Befehls wird kein Nullzeichen angezeigt und xargs wird _printf %b_ mit nur einem zusätzlichen Befehlszeilenargument ausgeführt, der Ausgabe von sed Befehl. Obwohl dies im Allgemeinen nicht äquivalent ist, könnte in diesem Fall die gesamte Pipeline stattdessen mit Befehlssubstitution anstelle von xargs wie folgt geschrieben worden sein:

_printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
_

Was printf hier tun soll, wie muru sagt der _%b_ Formatspezifizierer verbraucht und druckt ein Das Argument (wie _%s_) verursacht jedoch umgekehrte Schrägstriche - wie der Befehl sed auf der linken Seite der Pipe geschrieben wurde, um zu generieren - übersetzt in die Zeichen, die sie darstellen .

Angenommen, ich führe diesen Befehl aus und übergebe _http://foldoc.org/debugging%20by%20printf_ als Eingabe. Ich erhalte _http://foldoc.org/debugging by printf_ als Ausgabe, weil die _%20_ Sequenzen in Leerzeichen übersetzt werden.

10
Eliah Kagan

Das ist das Schöne an 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 richtig, etwas so Schreckliches zu schreiben wie:

echo 'arrival' | sed srarbrg

... und als Ergebnis brrivbl erhalten, was Sie erwarten. Sie können Spaß daran haben, es wirklich kryptisch zu machen, wie zum Beispiel in:

echo 'arrival' | sed s\fa\fb\fg   # \f is form feed, chr(12)

Der Schrägstrich wird häufig als Trennzeichen verwendet. Wenn Ihr Ausdruck jedoch das Trennzeichen enthält, ist es einfacher, die Absicht zu erfassen. Ihr Begrenzer kann ein beliebiger Wert im ASCII8-Bereich sein (Multibyte-Begrenzer wie £ rufen einen Fehler hervor).

Denken Sie daran, das Ziel ist es, die Dinge einfacher und nicht kryptischer zu machen.

3
Marabiloso