Aufbauend auf Lars zur Verfügung gestellt, die folgende Beschreibung ist in allen Versionen von sed arbeiten:
sed -e ':b' -e 's/\(|column7|\)\(.*\)|\(.*|2016|\)/\1\2 \3/' -e 'tb' inputfile
Dies funktioniert, indem wiederholt eingebettet Separatoren, bis die Ersatzmuster ersetzen kann nicht gefunden werden. Seds t
-Befehl verzweigt nur dann auf die :b
-Bezeichnung, wenn die vorherige Ersetzung erfolgreich war.
Wir verwenden die mehr klassischen BRE sowohl für die Kompatibilität und um zu vermeiden, sed interpretieren die vertikalen Balken als "oder" Separatoren in ERE.
Das sed-Skript ist in einzelne -e
-Optionen unterteilt, da einige Varianten von sed Label-Verweise auf "am Ende der Zeile" erfordern, und die Beendigung des Arguments -e
als gleichwertig mit dem Ende des Linie. (GNU sed erfordert dies nicht, aber eine Reihe anderer seds tun.)
Aber wie anubhava in Kommentaren hervorhebt, ist dies ein minderwertiger Ansatz, weil es fehlschlagen wird, wenn die Eingabedaten eine zweite 2016|
irgendwo in der rechts von der Spalte 9.
eine alternative Lösung, wenn Sie bash laufen lassen, könnte die Felder in ein Array zu platzieren, dann Elemente verschmelzen:
#!/usr/bin/env bash
input="column1|column2|column3|column4|column5|column6|column7|**col|u|lm|n8**|2016|column10|column11|column12|column13|column14|"
IFS=\| read -a a <<< "$input"
while [ "${a[8]}" != "2016" ]; do
a[7]="${a[7]} ${a[8]}" # merge elements
unset a[8] # delete merged element
a=("${a[@]}") # renumber array
done
printf "%s|" "${a[@]}"
Beachten Sie, dass Arrays mit dem Index starten bash 0 durch Standard. Das readarray
Built-in erlaubt es Ihnen, einen alternativen Startpunkt für Ihren Index anzugeben (-O
), aber dieser Built-In begann mit der Bash-Version 4, und es gibt immer noch eine Menge von Version 3 in freier Wildbahn. Also für Portabilität, read -a
ist es.
Beachten Sie auch, dass das obige Skript ohne weitere Fehlerprüfung in eine Endlosschleife geht, wenn Sie aus irgendeinem Grund in Ihren Eingabedaten kein "2016" -Feld haben. :-)
"en" ist die 7. Spalte also | en | col | u | m | n8 | 2016 ist Spalten 7, 8 und 9 mit Spalte 8 mit den zusätzlichen Leitungen – mk97
Wenn die Datei nur eine Zeile hätte, könnten Sie tun 'col8 = $ (sed 's/\ ([^ |] * | \) \ {7 \} \ (. * \) | 2016. */\ 2 /' Datei); echo "Debug-Zeile: col8 = $ {col8}, behoben $ {col8 // | /}"; sed 's/^ \ (\ ([^ |] * | \) \ {7 \} \). * | 2016/\ 1' "$ {col8 // | /} '' | 2016/'Datei' . Dies ist für Ihr Problem mit einer normalen Datei nicht hilfreich, da Sie eine langwierige While-Schleife erstellen müssen. –