2017-03-13 4 views
1

Wie mache ich eine Zeile bei jeder Ganzzahl gefolgt von dem Buchstaben Q und eine ganze Zahl?Bash Zeilenumbruch bei jeder Ganzzahl, gefolgt von bestimmten Zeichenfolge

Zum Beispiel:

echo "Lorem ipsum Que Q94 dolor sit amet, Q3004 consectetur adipiscing 
elit. Q1 Idcirco enim non desideraret" | sed -e $'s/Q\([0-9]\)/\\\nQ\1/g' 

generiert das folgende - falsche - Ergebnis:

Lorem ipsum Que 
Q4 dolor sit amet, 
Q004 consectetur adipiscing elit. 
Q Idcirco enim non desideraret 

Hinweis, wie die erste ganze Zahl nach jedem Q fehlt.

Das erwartete Ergebnis ist:

Lorem ipsum Que 
Q94 dolor sit amet, 
Q3004 consectetur adipiscing elit. 
Q1 Idcirco enim non desideraret 

Was bin ich?

Antwort

0

Ihre Nutzung von $'...' (ein ANSI C-quoted Bash string) schlägt vor, dass Sie verwenden BSD/macOSsed, wo \n Verwendung von Escape-Sequenz nicht in der Ersetzungsstring unterstützt.

Um Verwirrung zu vermeiden, zwischen \ -prefixed Sequenzen von $'...' vorne und den von sed interpretiert interpretiert zu entkommen, schlage ich vor $'\n'selektiv, durch Spleißen genau in das sed Skript bei Bedarf:

... | sed 's/Q[0-9]/\'$'\n''&/g' 
  • \ ist in der Ersatzzeichenfolge benötigt, um ein wörtlichen newline zu entkommen,

  • was ist, was ANSI C-quote Zeichenfolge erzeugt (bis zum Zeitpunkt sed sieht das Skript).

    • Beachten Sie, dass GNUsedtut Unterstützung \n in der Ersatzzeichenfolge, die den Befehl vereinfachen würde: ... | sed 's/Q[0-9]/\n&/g'
  • Ersatz-string Platzhalter & repräsentiert alles die regex abgestimmt (per POSIX).

    • Dies macht es unnötig, eine Capture-Gruppe, zu definieren, wie Sie versucht, und das verursacht das Problem im Tandem mit $'...' (siehe unten).

Was was Sie versucht:

Die Extraschicht durch die Verwendung von $'...' eingeführt Umschreibungen "aß" die \ Zeichen.so in Q\([0-9]\), dass sed sah Q([0-9]), die - in Abwesenheit von Nicht-Standard-Option -E zu aktivieren Regexes (ERE) erweitert - verursacht ( und ) als gewöhnlichen Zeichen behandelt werden (was sie in einem basic regular expression (BRE) sind, die sed verwendet standardmäßig).

So keine Einfanggruppe wurde definiert und \1 in der Ersatzzeichenfolge in dieleere Zeichenfolge expandiert.

2

Wenn Sie müde sind wie ich über alle diese sed Variationen (gnu, freebsd, öffnen bsd, macos) gibt es eine Lösung: Verwenden Sie perl -pe Ersatz.
Funktioniert in allen Maschinen gleich und Syntax ist fast identisch mit gnu sed. So wird diese in Debian getestet und wird gut auch in Ihrer Maschine arbeiten:

echo "...." |perl -pe 's/Q([0-9])/\nQ\1/g' 
+2

... oder etwas kürzer 'perl - pe 's/(Q \ d)/\ n $ 1/g'' :) – jm666

+0

@ jm666 Toller Tipp! Vielen Dank! –

+2

@ jm666: Oder, da es keine Notwendigkeit gibt, eine Erfassungsgruppe zu verwenden: 'perl -pe 's/Q \ d/\ n $ &/g''. – mklement0

0

GNU sed

sed 's/Q\([0-9]\)/\nQ\1/g' 

oder

sed 's/Q[0-9]/\n&/g' 
+1

Sie müssen darauf hinweisen, dass diese Lösung nur mit GNU Sed und nicht mit anderen Versionen von sed funktioniert (wie freebsd sed, openbsd sed, mac os sed, usw.). Gemessen an der sed-Syntax in OP, scheint es, dass OP GNU Sed nicht verwendet, so dass diese Lösung nicht auf seiner Maschine funktioniert, es sei denn, er entscheidet sich, gnu sed zu installieren. –

Verwandte Themen