
Начнем с простого примера генерации имени файла:
echo (xx|yy|zz)*.txt # Example 1
Это список всех txt-файлов, начинающихся с xx или yy или zz. Теперь давайте сгенерируем эти альтернативы динамически, используя подстановку команд; я использую echo
здесь только для иллюстрации того, куда я направляюсь; в примере из "реального мира" это, конечно, была бы какая-то программа:
echo $(echo '(xx|yy|zz)')*.txt # Example 2
Это будет работать так же, как указано выше. Теперь начинается сложная часть: подстановка команды должна предоставлять только ЧАСТЬ списка альтернатив:
echo ($(echo 'xx|yy')|zz)*.txt # Example 3 (does not work)
Это больше не будет работать: он найдет файлы, начинающиеся с zz, но не те, что с yy. Я думаю, Zsh ищет файлы, начинающиеся буквально с xx|yy
here.
Мы можем заставить это работать, если используем вспомогательную переменную:
list=$(echo 'xx|yy')
echo (${~list}|zz)*.txt # Example 4
Теперь мой вопрос:
Можно ли добиться эффекта примера 4, не используя временную переменную?
решение1
Просто используйте:
echo (${~"$(echo 'xx|yy')"}|zz)*.txt
Обратите внимание на кавычки вокруг подстановки команд, поскольку zsh
они выполняют разбиение слов, если не выполняют подстановку по умолчанию при подстановке команд, что может быть полезно в таких случаях, как:
echo (${~${(j:|:)$(cmd)}}).txt
для объединения слов в выводе cmd
with |
и интерпретации его как glob. См. также b
флаг расширения параметра, если вы не хотите, чтобы эти слова рассматривались как сами шаблоны:
echo (${~${(j:|:)${(b)$(cmd)}}}).txt