Intereting Posts
Как запустить несколько заданий в разных сеансах экрана в Bash-скрипте? Как выполнить скрипт после каждого автозапуска systemd? Разборка жесткого диска и устранение неполадок Debian не сохраняет предпочтения пользователя какой-либо программы Использование wget, как загрузить в определенное место, без создания папок и всегда перезаписывать исходные файлы Следите за временем ssh'd в рабочий компьютер для карты времени терминальная теория цвета Ввод пунктуации добавляет акцент на предыдущее письмо после того, как мой ноутбук состыкован в течение нескольких минут Как исправить мою установку llvm? NetworkManager пытается подключиться к предыдущей сети после приостановки, даже если сети нет Установка программ на съемном диске Linux fedora – пакет httpd и маршрутизатор, как заставить его работать? Установка Silent MySQL Server Рабочий стол Clear Linux не запускается на виртуальной машине Запуск сценария, когда пользователи подключаются через ssh

Разделить массив Zsh от подоболочки по переводу строки

Я хотел бы создать экземпляр массива zsh из подоболочки

myarray=($(somecommand) 

и я проверяю, получил ли я то, что хотел

 for element in $myarray ; do echo "===" ; echo $element ; echo "---" ; done 

По умолчанию я вижу, что пробелы (пробелы и разрывы строк) используются для разделения элементов.

Я также обнаружил, что могу использовать ${(s:-:)"$(somecommand)"} для разделения на - , в этом случае пробелы и разрывы строк не разбивают элементы (т.е. элементы массива могут содержать разрывы строк).

Пока что я не могу разбить только на разрывы строк. Т.е. если somecommand какая-то somecommand

 Alice Bob Arthur C Clarke Neo Thomas Anderson 

Я хочу, чтобы мой цикл for печатал:

 === Alice --- === Bob --- === Arthur C Clarke --- === Neo --- === Thomas Anderson --- 

Как мне этого добиться? (И, возможно, указатели, где искать это в руководстве.)

Собственный оператор расщепления (кроме расщепления слов по $IFS подобного Борну, который выполняется при подстановках команд без кавычек) с флагом расширения параметра s :

 array=(${(ps:\n:)"$(cmd)"}) 

будет разделять вывод команды cmd на новую строку, отбрасывая пустые элементы (пустые строки).

p – включить эти \x расширения. Поскольку ps:\n: является распространенным, он имеет более короткий псевдоним: f (для разделения на строки):

 array=(${(f)"$(cmd)"}) 

Чтобы сохранить пустые строки, вы должны сделать:

 array=("${(f@)$(cmd)"}) 

Теперь имейте в виду, что, как и в большинстве других оболочек, подстановка команд удаляет все завершающие символы новой строки, поэтому все завершающие пустые строки. Чтобы сохранить их, вы можете сделать:

 array=("${(f@)$(cmd; echo .)}") array[-1]=() # remove that last line added by echo . 

С разделением слов $IFS :

 IFS=$'\n' array=($(cmd)) # removes empty lines. Note that contrary to other # Bourne-like shells, zsh doesn't to globbing there # so you don't need the "set -o noglob" IFS=$'\n\n' # like in ksh93, doubling an IFS-whitespace character # removes its special treatment as a whitespace character array=($(cmd)) # preserves empty lines except the trailing ones IFS=$'\n\n' array=($(cmd; echo .)); array[-1]=() # preserves all empty lines. 

Чтобы избежать глобального изменения $IFS , вы можете сделать это в анонимной функции:

 (){ local IFS=$'\n\n' array=($(cmd; echo .)); array[-1]=() } 

Также помните, что расширение $array пропускает пустые элементы. Поэтому, если вы хотите перебрать все элементы, включая пустые, вам понадобится:

 for i ("$array[@]") ... 

или же

 for i ("${(@)array}") ... 

не

 for i ($array) ... for i in $array