dividere la linea lunga su un delimitatore


21

Quale comando posso usare per dividere l'input in questo modo:

foo:bar:baz:quux

in questo?

foo
bar
baz
quux

Sto cercando di capire il cutcomando ma sembra funzionare solo con quantità fisse di input, come "primi 1000 caratteri" o "primi 7 campi". Ho bisogno di lavorare con input arbitrariamente lunghi.


5
Intendi come tr : '\n' < input?
jw013,

Che shell stai usando? bash?
Glenn Jackman,

Risposte:


34

Ci sono alcune opzioni:

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

Puoi anche farlo in puro bash:

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

3
Notare che usare \nuna stringa di sostituzione come quella funzionerà in GNU sed, ma fallirà nella maggior parte delle altre implementazioni sed.
wjv,

@chrisdown C'è un modo per far funzionare i primi due in AIX?
cokedude,

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

4

Se il tuo grep supporta -opuoi farlo in questo modo:

grep -o '[^:]\+'

O con awk, impostando il separatore record su ::

awk -v RS=: 1

O con taglio GNU:

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

modificare

Come notato da Chris di seguito, questo lascerà una nuova riga finale, questo può essere evitato se il tuo awk supporta la specifica RScome espressione regolare (testato con GNU awk):

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

Il tuo awkesempio lascerà una nuova riga finale (probabilmente indesiderabile).
Chris Down,

@ChrisDown: hai ragione, questo può essere evitato se RS può essere un'espressione regolare.
Thor,

-1

In alcune stringhe ho avuto problemi con le soluzioni sopra. Ma questo ha funzionato per me:

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

Come scritto, questo non trasforma l'ingresso di esempio OP.
Kbulgrien,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.