Во-первых, я предполагаю, что использование 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если вы не хотите добавлять новую строку после строки.