разделить длинную строку на разделитель

21

Какую команду я могу использовать для разделения ввода следующим образом:

foo:bar:baz:quux

в это?

foo
bar
baz
quux

Я пытаюсь выяснить cutкоманду, но, кажется, она работает только с фиксированным количеством ввода, например, «первые 1000 символов» или «первые 7 полей». Мне нужно работать с произвольно длинным вводом.

japreiss
источник
5
Вы имеете в виду как tr : '\n' < input?
jw013
Какую оболочку вы используете? Баш?
Гленн Джекман

Ответы:

34

Есть несколько вариантов:

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

Вы также можете сделать это в чистом виде bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done
Крис Даун
источник
3
Обратите внимание, что использование \nв строке замены, подобной этой, будет работать в GNU sed, но не будет работать в большинстве других реализаций sed.
апреля
@ chrisdown Есть ли способ заставить первые два работать в AIX?
cokedude
4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux
Гленн Джекман
источник
4

Если ваш grep поддерживает, -oвы можете сделать это так:

grep -o '[^:]\+'

Или с помощью awk, установив разделитель записей на ::

awk -v RS=: 1

Или с вырезанным GNU:

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

редактировать

Как отметил Крис ниже, это оставит завершающий символ новой строки, этого можно избежать, если ваш awk поддерживает указание RSв качестве регулярного выражения (протестировано с GNU awk):

awk -v RS='[:\n]' 1
Тор
источник
Ваш awkпример оставит (вероятно, нежелательный) завершающий символ новой строки.
Крис Даун
@ChrisDown: вы правы, этого можно избежать, если RS может быть регулярным выражением.
Тор
-1

В некоторых строках у меня была проблема с решениями выше. Но это сработало для меня:

echo $string | sed 's/\\n/ /g' | tr " " \\n
Роберт
источник
Как написано, это не преобразует входные данные примера OP.
Кбулгриен