dividir una línea larga en un delimitador

21

¿Qué comando puedo usar para dividir entradas como esta?

foo:bar:baz:quux

¿dentro de esto?

foo
bar
baz
quux

Estoy tratando de descifrar el cutcomando, pero parece que solo funciona con cantidades fijas de entrada, como "primeros 1000 caracteres" o "primeros 7 campos". Necesito trabajar con entradas arbitrariamente largas.

japreiss
fuente
55
¿Quieres decir como tr : '\n' < input?
jw013
¿Qué caparazón estás usando? ¿golpetazo?
Glenn Jackman

Respuestas:

34

Hay algunas opciones:

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

También puedes hacer esto en puro bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done
Chris Down
fuente
3
Tenga \nen cuenta que usar una cadena de reemplazo como esa funcionará en GNU sed, pero fallará en la mayoría de las otras implementaciones de sed.
wjv el
@chrisdown ¿Hay alguna forma de hacer que los dos primeros funcionen en AIX?
cokedude
4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux
Glenn Jackman
fuente
4

Si su grep lo admite -o, puede hacerlo así:

grep -o '[^:]\+'

O con awk, configurando el separador de registros en ::

awk -v RS=: 1

O con corte GNU:

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

Editar

Como señala Chris a continuación, esto dejará una nueva línea final, esto se puede evitar si su awk admite la especificación RScomo una expresión regular (probada con GNU awk):

awk -v RS='[:\n]' 1
Thor
fuente
Su awkejemplo dejará una nueva línea final (probablemente no deseable).
Chris Down
@ChrisDown: tienes razón, esto se puede evitar si RS puede ser una expresión regular.
Thor
-1

En algunas cadenas tuve problemas con las soluciones anteriores. Pero esto funcionó para mí:

echo $string | sed 's/\\n/ /g' | tr " " \\n
Robert
fuente
Tal como está escrito, esto no transforma la entrada de ejemplo de OP.
kbulgrien