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


21

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

foo:bar:baz:quux

в это?

foo
bar
baz
quux

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


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

Если ваш 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.
Кбулгриен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.