In dieser Bearbeitung
POSIXifiziert Stéphane Chazelas (erneut) meine Formatierung, indem er eine xpression break- Anweisung und eine andere xpression-Anweisung einfügt. Nun, ich könnte ihn vielleicht fragen, warum in den Kommentaren, nehme ich an, aber es ist bereits die Revision Nummer 18 zu dieser Antwort und fast alle vorherigen waren bereits ähnlichen Werbegeschenken zu verdanken (wenn Sie gelöschte Kommentare sehen können, wissen Sie was Ich meine) . Ich denke auch, dass ich nahe genug dran bin, um zu verstehen, warum man dies in einer Weise formuliert, die allgemeiner nützlich sein könnte. Also hier ist die Hoffnung ... sed
-e
-e
Im Allgemeinen ziehe ich es vor, meinen sed
-e
Gesamtdruck auf einen zu beschränken, aber ich habe auch eine größere Vorliebe dafür, mich so nah wie möglich an die Spezifikation zu halten , insbesondere wenn der Unterschied nicht mehr als a <space>
und an beträgt -e
. Aber ich kann das nicht tun, wenn ich nicht verstehe, warum ich sollte. Hier ist ein kurzer Überblick über den aktuellen Stand meines Verständnisses:
Die
' -e '
Unterbrechung kann portabel für einesed
Skript-\n
Esed
-Line- Unterbrechung in einer Befehlszeilenanweisung stehen ... Ich bin zugegebenermaßen unklar, warumDer schließenden Klammer in einer
sed
{
Funktion}
muss ein\n
ewline-Umbruch vorausgehen, wie hier angegeben:- Dem
<right-brace>
muss ein vorangestellt sein<newline>
und es können<blank>
Zeichen vorangestellt oder gefolgt werden .
- Dem
eine
\n
ewline Pause wird nach jeder Verwendung auf ähnliche Weise erforderlich ...a
,b
,c
,i
,r
,t
,w
, oder:
.
Aber ich verstehe nicht klar, wie sich die {
Funktionsdefinition }
auf den !
Nicht-Operator bezieht . Die einzige Erwähnung, die ich vom Negationsoperator in der Spezifikation finde, ist:
- Einer Funktion können ein oder mehrere
!
Zeichen vorangestellt werden. In diesem Fall wird die Funktion angewendet, wenn die Adressen den Musterraum nicht auswählen.
Bedeutet dies, dass die Verwendung eines Klammern !
impliziert ? Was ist mit Befehlen - sollten sie ebenfalls durch Pausen getrennt sein ? Wurde dies angesprochen, als Stéphane zuletzt meine Antwort POSIXifizierte ?{
}
$!
' -e '
Ich denke, es ist entweder der !
Negationsoperator oder es ist die b
Ranch-Anweisung, die er in seiner Bearbeitung anspricht - oder möglicherweise beides gleichzeitig -, aber ich weiß es nicht und möchte es. Wenn es nur die b
Ranch Aussage, dann glaube ich , ein d
an seiner Stelle tun würde , und die Notwendigkeit der Beseitigung ' -e '
Pause, aber ich würde lieber sicher sein , bevor sie eine dreimal hazarding POSIXified Antwort. Kannst du helfen?
Ich habe es riskieren , schließlich , aber nicht mit großer Sicherheit ...
b;n;:b
verzweigen Sie zu dem Label, das";n;:b"
in historischen und POSIX-Seds genannt wird (und GNU sed ist diesbezüglich nicht der Fall).:
Teil - du bist das vor Monaten nach Hause gefahren. Aber ich verstehe nicht ganz, warum der zweitesed
Befehl ähnlich POSIXified war .sed
ist mir die POSIX-Spezifikation für sehr unklar. Ich habe in der Vergangenheit einige Male um Klarstellungen gebeten, aber ich glaube nicht, dass es als Ergebnis aktualisiert wurde. Ein guter Test ist der Versuch mit der Erbstück-Werkzeugkiste (Solaris, eine vom Original abgeleitete, auf der die POSIX-Spezifikation weitgehend basiert).s///
werden Sie feststellen, dass Substitutionen die Verkettung mit einem akzeptieren ; . Kommandos, die mit einem Zeilenumbruch abgegrenzt werden müssen, werden verschwommen und wie-e
kann man in diesem Fall stehen - zumindest für mich. Ich bin noch nicht auf einesed
gestoßen, die sie allerdings nicht wirklich austauschbar interpretiert.;
bevor eine neue Zeile - eine neue Zeile ist in Ordnung. Ehrlich gesagt, Sie könnten-e
ganz auf das und alles verzichten und einfach eine Datei wie#!/bin/sed
mit jedem Befehl in eine neue Zeile schreiben - oder solche, die keine solchen Trennzeichen benötigen, stattdessen mit;
. Diejenigen , die tun newlines erfordern , sind in der Regel diejenigen , die beliebige Eingaben nehmen -:
Markennamen und Befehle , die sich auf sie beziehen , wieb
odert
oder Schließen}
curlies für Funktionen oderr
ead undw
Ritus , die Dateinamen args nehmen. Sie alle müssen tragbar gefolgt werden\n
.Antworten:
Es ist also höchste Zeit, dass diese Frage beantwortet wird, und obwohl ich vor einiger Zeit so gut wie immer intuitiv herausgefunden habe, wie man das richtig macht, habe ich es erst vor kurzem geschafft, dieses Verständnis mit dem Text in der Norm einigermaßen zu konkretisieren . Es heißt dort eigentlich ziemlich einfach - ich habe es nur dumm oft übersehen, denke ich.
Die relevanten Teile des Textes befinden sich alle unter der Überschrift ...
Befehle bearbeiten in
sed
:Das Argument Text setzt sich aus einer oder mehreren Linien bestehen.
\n
Vor jeder eingebetteten ewline im Text muss ein\
Backslash stehen. Andere Backslashes im Text werden entfernt und das folgende Zeichen wird wörtlich behandelt.Die
r
undw
Befehlsverben und dasw
Flag an dens
Befehl, nehmen eine optionale RDATEI (oder wfile ) Parameter, von dem Befehlsverb Buchstaben oder Flag durch einen oder mehrere getrennt<blank>s
; Implementierungen können eine Trennung von Null als Erweiterung ermöglichen.Befehlsverb andere als
{
,a
,b
,c
,i
,r
,t
,w
,:
, und#
kann durch eine folgen;
Semikolon, optional<blank>s
, und ein anderes Befehlsverb. Wenn jedoch dass
Befehlsverb mit demw
Flag verwendet wird, führt das Verfolgen mit einem anderen Befehl auf diese Weise zu undefinierten Ergebnissen....im...
Optionen: Es können mehrere
-e
und-f
Optionen angegeben werden. Alle Befehle müssen unabhängig von ihrer Herkunft in der angegebenen Reihenfolge zum Skript hinzugefügt werden.-e
script - Fügen Sie die durch das script- Optionsargument angegebenen Bearbeitungsbefehle am Ende des Skripts der Bearbeitungsbefehle hinzu. Das Skript - Option-Argument hat die gleichen Eigenschaften wie das hat Skript Operanden in dem beschriebenen OPERANDS Abschnitt.-f
script_file - Fügen Sie die Bearbeitungsbefehle in der Datei script_file am Ende des Skripts hinzu.Und zuletzt in ...
Operanden:
\n
ewline sein muss.Wenn Sie also insgesamt davon ausgehen, ist es sinnvoll, dass jeder Befehl, auf den optional ein beliebiger Parameter ohne vordefinierten Begrenzer folgt (im Gegensatz zum
s d sub d repl d flag
Beispiel), an einer nicht entkappten\n
ewline begrenzt wird.Es ist fraglich , dass das
;
ist eine vordefinierte Trennzeichen , aber in diesem Fall ist die Verwendung;
für alle[aic]
Befehle erfordern würde , dass ein separater Parser bei der Umsetzung für diese drei Befehle speziell einbezogen werden - getrennt, die vom Parser für verwendet wird[:brw]
, zum Beispiel. Andernfalls müsste für die Implementierung;
auch ein Backslash innerhalb des text- Parameters angegeben werden, der von da an nur noch komplizierter wird.Wenn ich eine schreiben würde
sed
, die sowohl konform als auch effizient sein soll, würde ich vermutlich keinen solchen separaten Parser schreiben - außer, dass möglicherweise[aic]
ein Syntaxfehler\n
auftritt, wenn nicht sofort eine ewline folgt. Dies ist jedoch ein einfaches Tokenisierungsproblem - der Fall des Endbegrenzers ist im Allgemeinen problematischer. Ich würde es einfach so schreiben:...und...
... würde sich insofern sehr ähnlich verhalten, als der erste eine Datei mit dem Namen erstellen und in diese schreiben würde:
... und der zweite würde bei der Ausgabe einen Textblock an die aktuelle Zeile anhängen wie ...
... weil beide denselben Parsing-Code für den Parameter verwenden würden.
Und in Bezug auf das Thema
{ ... }
und$!
- nun, ich war weit weg. Ein einzelner Befehl, dem eine Adresse vorangestellt ist, ist keine Funktion, sondern nur ein adressierter Befehl. Fast alle Befehle - einschließlich der{
Funktionsdefinition -}
sind zum Akzeptieren/one/
oder/one/,/two/
Adressieren angegeben - mit Ausnahme von#
Kommentaren und:
Beschriftungsdefinition werden . Und eine Adresse kann entweder eine Zeilennummer oder ein regulärer Express sein und kann mit negiert werden!
. Also alles von ...... kann gefolgt werden von a
;
standardmäßig und mehreren Befehlen Wenn jedoch mehrere Befehle für eine einzelne Adresse erforderlich sind und diese Adresse nach der Ausführung jedes Befehls nicht erneut ausgewertet{
werden}
soll, sollte eine Funktion wie folgt verwendet werden:... wo
{
kann nicht in der gleichen Zeile von einem Closing}
und einem Closing gefolgt werden}
nur am Zeilenanfang erfolgen kann. Wenn einem enthaltenen Befehl jedoch keine\n
ewline folgen soll, muss er auch nicht in der Funktion enthalten sein. Auf alle obigens///
Substitutionen - und sogar auf die schließende}
Klammer - können also;
Semikolons und weitere Befehle portabel folgen .Ich spreche immer über
\n
ewline-Begrenzer, aber die Frage ist stattdessen über-e
xpression-Anweisungen, ich weiß. Aber die beiden sind wirklich ein und dasselbe, und die Schlüsselbeziehung ist, dass ein Skript entweder ein Literalbefehlszeilenargument oder eine Datei mit einem von beiden sein-[ef]
kann und dass beide als Textdateien interpretiert werden (die angegeben werden, um mit a zu enden)\n
ewline) aber weder Bedarf tatsächlich am Ende in einem\n
ewline. Auf diese Weise kann ich vernünftigerweise (wie ich hoffe) schließen, dass ein\0NUL
begrenztes Argument eine endende\n
ewline impliziert , und da alle Aufrufargumente mindestens ein\0NUL
Trennzeichen haben, sollte beides gut funktionieren.In der Tat, in der Praxis, in jedem Fall, außer einem, wo die Norm einen mit
\
Backslash-Escape versehenen Zeilenumbruch vorschreibt, habe ich tragbar festgestellt, dass ...... genauso gut zu arbeiten. Und in jedem Fall - auch in der Praxis - wo eine nicht
\n
entkoppelte ewline benötigt werden sollte ...... hat auch für mich gearbeitet. Die einzige Ausnahme, die ich oben erwähne, ist ...
... was bei keiner Implementierung in einem meiner Tests funktioniert. Ich bin ziemlich sicher , dass wieder auf den fällt Textdatei Bedarf und die Tatsache , dass
s///
kommt mit einem Trennzeichen und so gibt es keinen Grund , eine einzige Aussage sollte umspannt\0NUL
begrenzt Argumente.Im Folgenden finden Sie eine kurze Übersicht über die portablen Möglichkeiten, verschiedene Arten von
sed
Befehlen zu schreiben :Für irgendeinen von
[aic]
:...oder...
Für alle ,
[:rwtb]
wo der Parameter ist optional (für alle , aber:
) , aber die Begrenzungs\n
ewline ist nicht . Beachten Sie, dass ich habe noch nie einen Grund mehrzeilige versuchen Etikett als Parameter würde verwendet werden[:tb]
, aber dasw
riting /r
eading auf mehrere Zeilen in [rw] file Parameter in der Regel ohne Frage akzeptiertsed
s ich so lange wie das eingebettete getestet\n
ewline wird mit einem\
Backslash entkommen . Die Norm spezifiziert diese Kennzeichnungsparameter Parameter für und [rw] -Datei identisch mit dem Text analysiert werden sollen jedoch nicht direkt und erwähnt ewlines in Bezug auf die ersten beiden nicht, es sei denn, sie begrenzen sie.\n
...oder...
... wo das
<space>
obige optional ist für[:tb]
.Und zuletzt...
...oder...
... wobei eine der vorgenannten Befehle ( mit Ausnahme
:
) auch mindestens eine annehmen Adresse und die entweder eine sein kann/
regexp/
oder eine Zeilennummer und möglicherweise mit negiert werden!
, aber wenn mehr als ein Befehl für eine einzelne Auswertung der notwendig ist , Adresse dann Klammern zur Begrenzung des{
Funktionskontexts}
müssen verwendet werden. Eine Funktion kann sogar mehrere\n
ewline-getrennte Befehle enthalten, die jedoch innerhalb der geschweiften Klammern voneinander getrennt sein müssen, wie dies sonst der Fall wäre.Und so schreiben Sie portable
sed
Skripte.quelle