Ersetzen Sie n-ten Vorkommen von Zeichenfolgen in jeder Zeile einer Textdatei

23462
dnkb

Ich habe große Textdateien mit durch Leerzeichen getrennten Zeichenfolgen (2-5). Die Zeichenfolgen können "'" oder "-" enthalten. Ich möchte das zweite Feld durch ein Rohr ersetzen.

Was ist der beste Weg?

Mit sed habe ich darüber nachgedacht:

sed -r 's/(^[a-z'-]+ [a-z'-]+\b) /\1|/' filename.txt 

Irgendwelche anderen / besseren / einfacheren Ideen?

9

2 Antworten auf die Frage

12
mrucci

Sie können am Ende des Ersetzungsbefehls eine Nummer hinzufügen. Zum Beispiel ersetzt Folgendes das zweite Vorkommen von olddurch die Zeichenfolge newin jeder Zeile von file:

sed 's/old/new/2' file 

Anstelle Ihrer vorgeschlagenen Lösung können Sie also Folgendes verwenden:

sed 's/ /|/2' 

Weitere Informationen finden Sie zB in diesem Sed-Tutorial .

Aus der `sed`-Infodatei: *" Anmerkung: Der POSIX-Standard gibt nicht an, was passieren soll, wenn Sie die Modifizierer 'g' und 'NUMBER' mischen, und derzeit gibt es keine weit verbreitete Bedeutung für die Implementierung von 'sed'. Für GNU ` sed 'ist die Interaktion wie folgt definiert: Ignoriere Übereinstimmungen vor der NUMMERth und dann alle Übereinstimmungen ab der NUMBERth. Ersetzen und Ersetzen. "* Dennis Williamson vor 13 Jahren 2
Infodateien ... Ich hasse sie. Jedenfalls entfernte ich den mehrdeutigen Teil. Guter Kommentar, +1. mrucci vor 13 Jahren 0
Danke, mrucci und Dennis. Ich dachte, da draußen muss etwas einfaches sein. dnkb vor 13 Jahren 0
Es scheint, dass jedes Problem, das ich mit der Textmanipulation habe, ich mit "sed" lösen kann. Ich bin mir nicht sicher, ob ich Ihnen danken sollte, dass Sie "sed" noch nützlicher gemacht haben, aber ich werde es trotzdem tun. ;) Jamie vor 12 Jahren 0
1
petersohn

Hast du deine Version ausprobiert? Hat es funktioniert? Weil ich denke, dass es grundsätzlich eine gute Idee ist. Ich würde etwas anders machen:

sed -re 's/^([^ ]+ +[^ ]+) /\1|/' 

Dies akzeptiert alle Zeichen in einem Wort, das kein Leerzeichen ist, und akzeptiert mehr als ein Leerzeichen zwischen den ersten beiden Wörtern.