membagi garis panjang pada pembatas

21

Perintah apa yang dapat saya gunakan untuk membagi input seperti ini:

foo:bar:baz:quux

dalam hal ini?

foo
bar
baz
quux

Saya mencoba mencari tahu cutperintahnya tetapi sepertinya hanya berfungsi dengan jumlah input tetap, seperti "1000 karakter pertama" atau "7 bidang pertama". Saya perlu bekerja dengan input panjang yang sewenang-wenang.

japreiss
sumber
5
Maksudmu seperti tr : '\n' < input?
jw013
Shell apa yang Anda gunakan? pesta?
glenn jackman

Jawaban:

34

Ada beberapa opsi:

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

Anda juga dapat melakukan ini dengan murni bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done
Chris Down
sumber
3
Perhatikan bahwa menggunakan \nstring pengganti seperti itu akan berfungsi di GNU sed, tetapi akan gagal di sebagian besar implementasi sed lainnya.
wjv
@chrisdown Apakah ada cara agar dua yang pertama berfungsi di AIX?
Cokedude
4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux
glenn jackman
sumber
4

Jika grep -oAnda mendukung, Anda dapat melakukannya seperti ini:

grep -o '[^:]\+'

Atau dengan awk, atur pemisah rekaman ke ::

awk -v RS=: 1

Atau dengan potongan GNU:

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

Edit

Seperti dicatat oleh Chris di bawah ini, ini akan meninggalkan baris baru, ini dapat dihindari jika dukungan awk Anda menentukan RSsebagai ekspresi reguler (diuji dengan GNU awk):

awk -v RS='[:\n]' 1
Thor
sumber
awkContoh Anda akan meninggalkan baris baru (mungkin tidak diinginkan).
Chris Down
@ ChrisDown: Anda benar, ini bisa dihindari jika RS bisa menjadi ekspresi reguler.
Thor
-1

Dalam beberapa string saya punya masalah dengan solusi di atas. Tetapi ini berhasil bagi saya:

echo $string | sed 's/\\n/ /g' | tr " " \\n
Robert
sumber
Seperti yang ditulis, ini tidak mengubah input contoh OP.
kbulgrien