Lange Zeile auf Trennzeichen teilen

21

Welchen Befehl kann ich verwenden, um die Eingabe wie folgt zu teilen:

foo:bar:baz:quux

das mögen?

foo
bar
baz
quux

Ich versuche, den cutBefehl herauszufinden, aber er scheint nur mit festen Eingabemengen zu funktionieren, wie "ersten 1000 Zeichen" oder "ersten 7 Feldern". Ich muss mit beliebig langen Eingaben arbeiten.

japreiss
quelle
5
Du meinst wie tr : '\n' < input?
jw013
Welche Shell benutzt du? Bash?
Glenn Jackman

Antworten:

34

Es gibt einige Möglichkeiten:

  • tr : \\n
  • sed 's/:/\n/g'
  • awk '{ gsub(":", "\n") } 1'

Sie können dies auch in reinem tun bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done
Chris Down
quelle
3
Beachten Sie, dass die Verwendung \ndieser Ersatzzeichenfolge in GNU sed funktioniert, in den meisten anderen sed-Implementierungen jedoch fehlschlägt.
WJV
@chrisdown Gibt es eine Möglichkeit, die ersten beiden unter AIX zum Laufen zu bringen?
Koksud
4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux
Glenn Jackman
quelle
4

Wenn dein grep dies unterstützt -o, kannst du es so machen:

grep -o '[^:]\+'

Oder setzen Sie mit awk das Datensatztrennzeichen auf ::

awk -v RS=: 1

Oder mit GNU-Schnitt:

cut -d: --output-delimiter=$'\n' -f1-

Bearbeiten

Wie von Chris unten bemerkt, hinterlässt dies eine neue Zeile. Dies kann vermieden werden, wenn Ihre awk die Angabe RSeines regulären Ausdrucks unterstützt (getestet mit GNU awk):

awk -v RS='[:\n]' 1
Thor
quelle
Ihr awkBeispiel hinterlässt eine (wahrscheinlich unerwünschte) nachgestellte Zeile.
Chris Down
@ ChrisDown: Sie haben Recht, dies kann vermieden werden, wenn RS ein regulärer Ausdruck sein kann.
Thor
-1

Bei einigen Saiten hatte ich Probleme mit den obigen Lösungen. Aber das hat bei mir geklappt:

echo $string | sed 's/\\n/ /g' | tr " " \\n
Robert
quelle
Wie geschrieben, transformiert dies den OP-Beispieleingang nicht.
kbulgrien