podziel długą linię na separatorze


21

Jakiego polecenia mogę użyć do podzielenia danych wejściowych w ten sposób:

foo:bar:baz:quux

zaangażowany w to?

foo
bar
baz
quux

Próbuję rozgryźć cutpolecenie, ale wydaje się, że działa ono tylko ze stałą ilością danych wejściowych, takich jak „pierwsze 1000 znaków” lub „pierwsze 7 pól”. Muszę pracować z dowolnie długim wkładem.


5
Masz na myśli tr : '\n' < input?
jw013,

Jakiej powłoki używasz? grzmotnąć?
glenn jackman

Odpowiedzi:


34

Istnieje kilka opcji:

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

Możesz to również zrobić w czystej postaci bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done

3
Zauważ, że użycie \ntakiego zastępującego ciągu będzie działać w GNU sed, ale zawiedzie w większości innych implementacji sed.
wjv

@chrisdown Czy istnieje sposób, aby pierwsze dwa działały w systemie AIX?
Cokedude

4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux

4

Jeśli twój grep obsługuje -o, możesz to zrobić w następujący sposób:

grep -o '[^:]\+'

Lub za pomocą awk, ustawiając separator rekordów na ::

awk -v RS=: 1

Lub z cięciem GNU:

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

Edytować

Jak zauważył Chris poniżej, pozostawi to końcowy znak nowej linii, można tego uniknąć, jeśli awk obsługuje określanie RSjako wyrażenie regularne (testowane z GNU awk):

awk -v RS='[:\n]' 1

Twój awkprzykład pozostawi (prawdopodobnie niepożądany) końcowy znak nowej linii.
Chris Down,

@ChrisDown: masz rację, można tego uniknąć, jeśli RS może być wyrażeniem regularnym.
Thor

-1

W niektórych ciągach miałem problem z powyższymi rozwiązaniami. Ale to zadziałało dla mnie:

echo $string | sed 's/\\n/ /g' | tr " " \\n

Jak napisano, nie przekształca to przykładowego wejścia OP.
kbulgrien
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.