Hier ist eine andere Möglichkeit, die der Antwort von Wildcard sehr ähnlich ist :
files=( file1.csv file2.csv)
eval paste "<( cut -d, -f1 ${^files[@]} )"
Anstelle einer for
Schleife wird die ${^ ... }
Erweiterung verwendet, die Zsh-spezifisch ist.
Der Grund files
, der zuerst zugewiesen werden muss, ist, dass das Globbing immer zuletzt durchgeführt wird. Wenn files
also automatisch (wie in files=( *.csv )
) generiert werden muss, wird so etwas ${^:-( *.csv )}
erst erweitert, nachdem alle anderen Erweiterungen aufgetreten sind. Wir wollen, dass es zuerst erweitert wird .
Die ${^ ... }
Erweiterung bewirkt, dass sich das resultierende Array wie das Ergebnis der Klammererweiterung verhält. Zuweisen x=(a b)
und dann vergleichen echo ${x}y
mit echo ${^x}y
.
Das Anführungszeichen ist notwendig, um Zsh dazu zu bringen, den umgebenden Text wie eine wörtliche Zeichenfolge zu behandeln. Andernfalls würde die Befehlszeile an den Leerzeichen aufgeteilt, sodass sich unsere ${^ ... }
Erweiterung auf reduzieren würde ""${^ ... }""
. Das heißt, jedes Element würde nur von einer leeren Zeichenfolge umgeben sein. Das ist,
echo "<( cut -d, -f1 ${^files[@]} )"
und
echo "<( cut -d, -f1 "\
${^files[@]}\
" )"
sind gleichwertig, aber nicht dasselbe wie
echo <( cut -d, -f1 ${^files[@]} )
Das Zitieren bringt jedoch ein neues Problem mit sich: Die Befehlszeile wird analysiert und aufgeteilt, ohne Rücksicht auf die stattfindende Erweiterung. Das heißt, obwohl wir effektiv eingetreten sind
paste <( cut -d, -f1 file1.csv ) <( cut -d, -f1 file2.csv )
wie gewünscht wird dies tatsächlich als analysiert
paste '<( cut -d, -f1 file1.csv )' '<( cut -d, -f1 file2.csv )'
Daher müssen wir eval
den korrekt geformten Ausdruck neu analysieren. Vergleichen Sie dies, um dies in Aktion zu sehen
setopt noxtrace
eval paste "<( cut -d, -f1 ${^files[@]} )" 1>/dev/null 2>&1
zu
setopt xtrace
eval paste "<( cut -d, -f1 ${^files[@]} )" 1>/dev/null 2>&1
Ich hoffte , dass eine Kombination von verschachtelten Erweiterungen, die ${ ... :- ... }
Erweiterung und dem Parameter Expansion Flags Q
, z
und / oder s
würde ohne zu einer Neubewertung führen eval
, aber offenbar nicht der Fall ist. Ich wünschte auch, es gäbe einen Weg, das Globbing zu erzwingen, aber auch das scheint unmöglich.