#bash #shell #zsh
Вопрос:
У меня есть список строковых записей, разделенных пробелами
words="foo bar baz"
и я хочу красиво напечатать их, каждый в новой строке, с дефисом:
- foo
- bar
- baz
Как я могу этого достичь?
Я нашел много способов замены пробелов новыми строками, например
tr ' ' 'n' <<< $words
но мне не повезло применить их вместе с дефисом и пробелом… по какой-то причине следующие две строки возвращают один и тот же результат:
tr ' ' 'n' <<< $words
tr ' ' 'n- ' <<< $words
У меня также возникли проблемы с добавлением первого элемента, "- "
не нарушая новые строки в выводе консоли.
Ответ №1:
Мог бы сделать
words="foo bar baz";b=( $words );for i in ${!b[@]}; do echo "- ${b[$i]}";done
Комментарии:
1. Ну, если это массив, то просто
printf "- %sn" "${b[@]}"
2. @KamilCuk Конечно. Недостаточно использовать printf, чтобы быть моим первым рефлексом. Хорошая альтернатива.
3. Ну, тогда, если использовать разделение слов, то это просто
printf "- %sn" $words
Ответ №2:
sed
кажется милым:
sed 's/ /n- /g; s/^/- /' <<<"$words"
или:
tr ' ' 'n' <<< $words | sed 's/^/- /'
Если $words
простые слова разделены пробелами без каких-либо причудливых символов, подобных *
?
[
подобным, вы могли бы
printf -- "- %sn" $words
Обратите внимание, что расширения переменных без кавычек подвергаются разделению слов и расширению имени файла.
Комментарии:
1. Отлично работает, спасибо! Знаете ли вы, почему
tr ' ' 'n- ' <<< $words
иtr ' ' 'n' <<< $words
возвращает один и тот же вывод?2.
tr
например, сопоставляет символы 1:1 из списка. Так , напримерtr abc def
, измененияa
вd
,b
вe
иc
f
в. Вызовtr ' ' 'n-'
преобразует пространство вn
и в основном-
, и пространство не сопоставляется ни с какими входными данными, поэтому они просто игнорируются.tr
это какy
командованиеsed
.
Ответ №3:
С awk
:
awk 'BEGIN {RS=" "} {print "- " $0}' <<< "${words}"
Ответ №4:
Это делает серия команд sed:
sed 's/.*="//; s/"$//; s/ /n/g;' <test | sed 's/^/- /'
Редактировать: Упс, я думал, что words="foo baz bar"
это содержимое файла…
У @KamilCuk есть гораздо более чистый способ.
Ответ №5:
Версия для zsh
, основанная на некоторых других ответах и комментариях:
printf -- '- %sn' ${=words}
В zsh
, это может обрабатывать специальные символы, такие как подстановочные знаки:
% words="foo? 'b'ar *bar b[a-z]"
% printf -- '- %sn' "${=words}"
- foo?
- 'b'ar
- *bar
- b[a-z]