2

Я пытаюсь выяснить, как сделать команду для нескольких элементов. Например:

mycommmand fileA; mycommand fileB; mycommand fileC;

Я могу сделать это так:

files=(fileA fileB fileC)
for fl in $files; mycommand $fl

Когда я пытаюсь вставить это, это терпит неудачу:

$for fl in (fileA fileB fileC); echo $fl
zsh: invalid mode specification

Это возможно в Zsh? Я просмотрел руководство по массивам, но там не упоминалось, как это сделать.

2 ответа2

5
$for fl in (fileA fileB fileC); echo $fl

Здесь ( анализируется как начало классификатора глобуса, как в ls *(a+2) .

Квалификатор f обозначает файлы со спецификацией соответствия прав доступа, поэтому вы получаете спецификацию режима недопустимого ошибки, поскольку ileA не является действительной спецификацией права доступа.

Если вы попробуете, например, $for fl in (anotherfileA fileB fileC); echo $fl вы получите zsh: number expected потому что спецификатор должен выбрать по времени доступа. И так далее...

Итак, как это сделать правильно? - В zsh есть два возможных синтаксиса для циклов for :#

  • Номер один описан в справочной странице:

    for name ... [ in word ... ] term do list done
    

    Итак, как уже указывал @SadBunny , правильный синтаксис вашего примера

    for fl in fileA fileB fileC; echo $fl
    
  • Номер 2 предназначен для таких ленивых людей, как я (считайте нажатия клавиш ;) ), описанных в разделе « Альтернативные формы для сложных команд » в man zshmisc:

    for name (word ...) { cmd1; cmd2; }
    

    что можно упростить только для одной команды в теле цикла, исключив фигурные скобки:

    for fl (fileA fileB fileC) echo $fl
    

    Эта форма ИМХО имеет два основных преимущества:

    • легче запомнить (ровно одна пара круглых скобок, нет или одна пара фигурных скобок)
    • работает как for fl (fileA fileB fileC) mycommand $fl так и for fl ($files) mycommand $fl - тот же синтаксис для литеральных значений или переменных.

# Не считая арифметику для циклов в форме for (( [expr1] ; [expr2] ; [expr3] )) do list done

1

Конечно, это возможно. Снимите скобки:

monsterkill-ub-dt% for fl in (xfile yfile); cat ${fl}
zsh: invalid mode specification

monsterkill-ub-dt% for fl in xfile yfile; cat ${fl}  
x
y

Это также работает:

monsterkill-ub-dt% for fl in *; cat ${fl} 
x
y

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .