dividir linha longa em um delimitador

21

Que comando posso usar para dividir entradas como esta:

foo:bar:baz:quux

nisso?

foo
bar
baz
quux

Estou tentando descobrir o cutcomando, mas parece funcionar apenas com quantidades fixas de entrada, como "primeiros 1000 caracteres" ou "primeiros 7 campos". Eu preciso trabalhar com entradas arbitrariamente longas.

japreiss
fonte
5
Você quer dizer como tr : '\n' < input?
Jw013
Qual shell você está usando? bater?
perfil completo de Glenn Jackman

Respostas:

34

Existem algumas opções:

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

Você também pode fazer isso de maneira pura bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done
Chris Down
fonte
3
Observe que o uso \nna cadeia de substituição como essa funcionará no GNU sed, mas falhará na maioria das outras implementações do sed.
Wjv 04/11
@chrisdown Existe uma maneira de fazer com que os dois primeiros trabalhem no AIX?
cokedude 23/10
4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux
Glenn Jackman
fonte
4

Se o seu grep suportar, -ovocê pode fazer o seguinte:

grep -o '[^:]\+'

Ou com o awk, configurando o separador de registros para ::

awk -v RS=: 1

Ou com o corte GNU:

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

Editar

Conforme observado por Chris abaixo, isso deixará uma nova linha à direita; isso poderá ser evitado se o seu awk suportar a especificação RScomo uma expressão regular (testada com o GNU awk):

awk -v RS='[:\n]' 1
Thor
fonte
Seu awkexemplo deixará uma nova linha (provavelmente indesejável) à direita.
Chris Baixo
@ ChrisDown: você está certo, isso pode ser evitado se o RS puder ser uma expressão regular.
Thor
-1

Em algumas strings, tive problemas com as soluções acima. Mas isso funcionou para mim:

echo $string | sed 's/\\n/ /g' | tr " " \\n
Robert
fonte
Conforme escrito, isso não transforma a entrada de exemplo OP.
kbulgrien