Как перебирать строку по одному слову за раз в zsh
Как мне изменить следующий код, чтобы при запуске в zsh он расширял $things
и повторял их по одному за раз?
things="one two"
for one_thing in $things; do
echo $one_thing
done
Я хочу, чтобы выход был:
one
two
Но, как написано выше, он выводит:
one two
(Я ищу поведение, которое вы получаете при запуске вышеуказанного кода в bash)
Ответы
Ответ 1
Чтобы увидеть поведение, совместимое с оболочкой Bourne, вам нужно установить опцию SH_WORD_SPLIT
:
setopt shwordsplit # this can be unset by saying: unsetopt shwordsplit
things="one two"
for one_thing in $things; do
echo $one_thing
done
создаст:
one
two
Однако он рекомендовал использовать массив для создания разбиения слов, например
things=(one two)
for one_thing in $things; do
echo $one_thing
done
Вы также можете обратиться к:
3.1: Почему $var, где var = "foo bar" не выполняет то, что я ожидаю?
Ответ 2
Вы можете использовать флаг расширения z
для разделения слов на переменной
things="one two"
for one_thing in ${(z)things}; do
echo $one_thing
done
Подробнее об этом и других переменных флагах в man zshexpn
читайте в разделе "Флаги расширения параметров".
Ответ 3
Вы можете считать, что внутренний разделитель полей (IFS) на bash равен \x20 (пробел). Это делает следующую работу:
#IFS=$'\x20'
#things=(one two) #array
things="one two" #string version
for thing in ${things[@]}
do
echo $thing
done
С учетом этого вы можете реализовать это разными способами, просто манипулируя IFS; даже в многострочных строках.