Wie kann ich BSD sed anweisen, Escape-Sequenzen wie \n und \t zu interpretieren?

Wie kann ich BSD sed anweisen, Escape-Sequenzen wie \n und \t zu interpretieren?

Ich habe einen sed-Ersatzbefehl, der sowohl mit BSD sedals 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 seds 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 sedinterpretiert die Escape-Sequenzen jedoch nicht und GNUsed tut. Was ist die geeignete Art, Anweisungen sedzum 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 \nund \twerden von BSD nicht als Escape-Sequenzen interpretiertsed

Nun zu meiner Frage. Laut der BSD- sedManpage:

Um in der Ersetzungszeichenfolge ein Zeilenumbruchzeichen anzugeben, stellen Sie ihm einen Backslash voran.

Bedeutet dies, dass ich vor einerwörtlichZeilenumbruch durch Backslash? Wie werden sedEscape-Sequenzen am besten interpretiert, wie \nim 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 \tund \nnicht portierbar, außer in einemregulärer Ausdruck, \nsteht für eine neue Zeile. Im Ersetzungstext für einen sBefehl \nist 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/'
}

sBeachten 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:

https://stackoverflow.com/questions/1421478/wie-verwende-ich-einen-neuen-Zeilenaustausch-in-einem-BSD-Sed

Es ist so ziemlich genau das, was jw013 gesagt hat.

Um einen wörtlichen Tabulator einzufügen, geben Sie ctrl+ ein VTab.

verwandte Informationen