#bash #zsh
#bash #zsh
Вопрос:
Недавно я переключился с bash на zsh и не уверен, как этого добиться:
bash:
$ list='aaa
> bbb
> ccc
> ddd'
$ for i in $list; do echo $i-xxx; done
aaa-xxx
bbb-xxx
ccc-xxx
ddd-xxx
в zsh я получаю:
% list='aaa
quote> bbb
quote> ccc
quote> ddd'
% for i in $list; do echo $i-xxx; done
aaa
bbb
ccc
ddd-xxx
как заставить zsh делать это так же, как bash?
Комментарии:
1. Вы должны использовать массивы в обеих оболочках вместо того, что вы пытаетесь.
2. Проблема в том, что
zsh
по умолчанию не выполняется разделение слов при расширении параметра без кавычек. Существует опция, которую вы можете настроить, чтобы заставить ее делать это, но использование строки таким образом также не рекомендуетсяbash
.
Ответ №1:
Скорее всего, рассмотрите возможность использования массива вместо:
arraylist=(aaa bbb ccc ddd)
for i in "${arraylist[@]}"; do echo "$i-xxx"; done
Кажется, вы хотите выполнить итерацию по строкам в переменной, поэтому вы хотите сделать:
while IFS= read -r i; do echo "$i-xxx"; done <<<"$list"
Если вы хотите добавить к каждой строке строку, используйте вместо -xxx
sed
:
sed 's/$/-xxx/' <<<"$line"
Также есть xargs
:
xargs -d'n' -i echo {}-xxx <<<"$line"
Если вы хотите перебирать слова в строке, а слова могут быть в двойных кавычках, я бы выбрал xargs
:
xargs -i echo {}-xxx <<<"$line"
Если вы хотите перебирать слова в строке без интерпретации кавычек, способ в другом ответе с for i in $(echo $list)
помощью совместим как с zsh, так и с bash
Комментарии:
1. это эхо — это только пример, я бы хотел выполнять разные действия для каждой строки в цикле итерации для каждой строки.. это может быть curl, nc или любая другая команда, где строка будет параметром..
Ответ №2:
Вы можете использовать флаг расширения параметра, чтобы разделить строку на новые строки:
for line in ${(f)list}; do ...
Смотрите http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
Комментарии:
1. Вы также можете использовать
$=list
для разделения строки, используя символы, из$IFS
которых включает в себя новые строки. Это ближе к поведению bash.setopt shwordsplit
также выполнит эту работу.
Ответ №3:
Вы должны разделить свою строку list
на пробелы:
for i in ${(z)list}
do
echo $i
done
Конечно, вопрос в том, почему вы list
в первую очередь определили как скаляр. Даже в bash, возможно, было бы разумнее использовать его как массив. В Zsh массив был бы (возможно — зависит от того, что еще вы хотите с ним сделать) даже более удобным, чем одна строка.