Во-первых, я предполагаю, что использование ls
является лишь примером. Вы не можете анализировать вывод ls
в любой оболочке, потому что это неоднозначно. Прочтите Почему вы не должны анализировать вывод ls (1), если это новость для вас. В любой оболочке для получения списка файлов используйте подстановочные знаки, например files=(*)
.
В zsh, как и в других оболочках, результат подстановки команды разбивается на слова с пробельными символами (точнее, в соответствии со значением IFS
). (В отличие от других оболочек, результат подстановки команды не подлежит смещению в zsh.) Поэтому, если вывод ls
команды
hello world
wibble
затем files=($(ls))
устанавливает files
массив содержит 3 элемента: hello
, world
и wibble
.
Если подстановка команды в двойных кавычках, то расщепление не выполняется. Вы можете выполнить произвольное разбиение с помощью флагов расширения параметров . Используйте @
флаг, чтобы указать, что результатом разбиения должен быть массив (как ни странно, вам нужно хранить раскрытие в двойных кавычках, т. Е. "${(@)…}"
Даже если строка в двойных кавычках будет расширяться до нескольких слов). Для разделения используйте s
флаг, например, "${(@s:,:)…}"
чтобы разделить запятыми; f
флаг расщепляется на только переводы строк.
files=("${(@f)$(ls)}")
Обратите внимание, что правильный способ перебора массива в целом заключается for f in $files[@]
в $files
удалении пустых элементов (здесь это не имеет значения, поскольку элементы не будут пустыми).
print $f
интерпретируется $f
как переключатель, если он начинается с -
и расширяется обратным слешем в $f
. Используйте print -r -- $f
, или print -rn -- $f
если вы не хотите добавлять новую строку после строки.