Wie füge ich in Bash Text nach dem n-ten Vorkommen hinzu?

Wie füge ich in Bash Text nach dem n-ten Vorkommen hinzu?

Nehmen wir an, ich habe helloworld.txt:

hello world

Mit sed:

sed 's/w*/goodbye/' helloworld.txt

Gibt mir:

goodbyehello world

Und:

sed 's/$/goodbye/' helloworld.txt

Gibt mir:

hello worldgoodbye

Aber wie füge ich Text hinzu?nachdas erste Vorkommen, also sieht es folgendermaßen aus:

hellogoodbye world

Antwort1

Angenommen, Sie sprechen über das Einfügen von Text vor oder nach bestimmten Vorkommen vonWörterin einer Textzeile.

$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/newword &/'
newword word1 word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/'
word1 newword word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/2'
word1 word2 newword word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/3'
word1 word2 word3 newword word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/4'
word1 word2 word3 word4 newword

Dadurch wird die Zeichenfolge newword(und ein vorangestelltes Leerzeichen) an verschiedenen Stellen in der angegebenen Zeichenfolge eingefügt.

Der sedAusdruck

s/\<[[:alnum:]]\{1,\}\>/& newword/2

ersetzt die zweite Übereinstimmung durch eine nicht leere Zeichenfolge, die nur aus alphanumerischen Zeichen besteht.

Das flankierende \<und \>stimmt mit der Nullbreite-Grenze zwischen einem Wort und einem Nicht-Wort am Anfang bzw. Ende der Übereinstimmung überein (in GNU sedkönnen Sie hierfür auch verwenden \b). Dies stellt sicher, dass Sie ganze Wörter abgleichen, ist aber bei den gegebenen Daten nicht wirklich erforderlich (ich verwende die Wortgrenzenmuster, da dies die Absicht meines Vorgehens unterstreicht).

Dies \{1,\}ist ein Modifikator, der in einen erweiterten regulären Ausdruck geschrieben wird +und dafür sorgt, dass das vorhergehende Muster mindestens einmal übereinstimmt ( sedstandardmäßig werden jedoch grundlegende reguläre Ausdrücke verwendet).

Im Ersetzungsteil &befindet sich das Bit der Eingabezeichenfolge, das tatsächlich mit dem Muster übereinstimmt, und am 2Ende steht ein Flag, das die Ersetzung nur für die zweite, nicht überlappende Übereinstimmung bewirkt.

Die Beispielein deinem Kommentar(was fast dasselbe ist, aber ohne Einfügen des Leerzeichens):

$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/'
7DF258FIDUCIAL 01DB-MET-RX PASS
$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/2'
7DF258 01DB-MET-RXFIDUCIAL PASS

Beachten Sie, dass in dem Beispiel, das Sie in den Kommentaren angegeben haben, die „Wörter“ auch Bindestriche enthalten. Aus diesem Grund verwende ich [[:alnum:]-]anstelle von nur [[:alnum:]].

verwandte Informationen