Ich habe einen sed-Ersatzbefehl, der sowohl mit BSD sed
als auch mit GNU kompatibel sein soll sed
. Erweiterte reguläre Ausdrücke sind kein Problem, da ich sie in diesem Fall nicht benötige. Mein Hauptproblem ist der Unterschied in der Art und Weise, wie die beiden sed
s Escape-Sequenzen für Zeichen interpretieren.ErsatzZeichenfolgen. Meine Ersatzzeichenfolge enthält Tabulatoren und Zeilenumbrüche und ich möchte, dass sie in den Befehlszeichenfolgen sichtbar sind, um die Wartung zu erleichtern. BSD sed
interpretiert die Escape-Sequenzen jedoch nicht und GNUsed
tut. Was ist die geeignete Art, Anweisungen sed
zum Interpretieren dieser Escape-Sequenzen unter BSD zu geben? Die folgenden beiden Ausschnitte veranschaulichen mein Problem:
GNUsed
echo ABC | sed 's/B/\n\tB\n'
Erträge
A
B
C
BSDsed
echo ABC | sed 's/B\n\tB\n'
Erträge
AntBnC
Offensichtlich \n
und \t
werden von BSD nicht als Escape-Sequenzen interpretiertsed
Nun zu meiner Frage. Laut der BSD- sed
Manpage:
Um in der Ersetzungszeichenfolge ein Zeilenumbruchzeichen anzugeben, stellen Sie ihm einen Backslash voran.
Bedeutet dies, dass ich vor einerwörtlichZeilenumbruch durch Backslash? Wie werden sed
Escape-Sequenzen am besten interpretiert, wie \n
im Ersetzungstext?
Antwort1
Sie können die Bash- $'...'
Anführungszeichen verwenden, um die Escape-Zeichen zu interpretieren, bevor Sie die Zeichenfolge an übergeben sed
.
Aus der Bash-Manpage:
Words of the form $'string' are treated specially. The word
expands to string, with backslash-escaped characters replaced as
specified by the ANSI C standard. Backslash escape sequences, if
present, are decoded as follows:
\a alert (bell)
\b backspace
\e an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\nnn the eight-bit character whose value is the octal
value nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadeci-
mal value HH (one or two hex digits)
\cx a control-x character
The expanded result is single-quoted, as if the dollar sign had
not been present.
A double-quoted string preceded by a dollar sign ($) will cause
the string to be translated according to the current locale. If
the current locale is C or POSIX, the dollar sign is ignored. If
the string is translated and replaced, the replacement is double-
quoted.
Antwort2
Wenn Sie portable Skripte schreiben müssen, sollten Sie sich an die Funktionen in derPOSIX-Standard(auch bekannt als Single Unix oder Open Group Base Specification).Ausgabe 7, auch bekannt als POSIX-1.2008ist die neueste Version, wird jedoch in vielen Systemen noch nicht vollständig übernommen.Ausgabe 6, auch bekannt als POSIX-1.2001wird im Großen und Ganzen von allen modernen Unix-Geräten bereitgestellt.
Insedist die Bedeutung von Escape-Sequenzen wie \t
und \n
nicht portierbar, außer in einemregulärer Ausdruck, \n
steht für eine neue Zeile. Im Ersetzungstext für einen s
Befehl \n
ist nicht portierbar, aber Sie können die Sequenz Backslash-Newline verwenden, um für eine neue Zeile zu stehen.
Eine portable Möglichkeit, ein Tabulatorzeichen (oder jedes andere oktal ausgedrückte Zeichen) zu erzeugen, ist mittr
. Speichern Sie das Zeichen in einer Shell-Variable und ersetzen Sie diese Variable im Sed-Snippet.
tab=$(echo | tr '\n' '\t')
escape=$(echo | tr '\n' '\033')
embolden () {
sed -e 's/^/'"$escape"'[1m/' -e 's/$/'"$escape"'[0m/'
}
s
Beachten Sie erneut, dass Zeilenumbrüche in regulären Ausdrücken und in Ersetzungstexten unterschiedlich ausgedrückt werden müssen .
Vielleicht möchten Sie verwendenawkstattdessen. Es erlaubt Backslash-Escapes, einschließlich Oktal-Escapes \ooo
, in jedem Stringliteral.
Antwort3
Dies wurde auf Stack Overflow beantwortet:
Es ist so ziemlich genau das, was jw013 gesagt hat.
Um einen wörtlichen Tabulator einzufügen, geben Sie ctrl+ ein VTab.