Ecco alcuni altri modi per fare ciò che stai cercando con note su pro e contro.
Quanto segue funziona solo con nomi file che non includono il ritorno a capo. Si accoppia i file in un attimo. Usa un descrittore di file aggiuntivo per leggere dal primo elenco. Se im1_dir
contiene più file, il ciclo si arresterà quando si esaurisce lo im2_dir
. Se im2_dir
contiene più file, file1
sarà vuoto per tutti gli impareggiabili file2
. Naturalmente se contengono lo stesso numero di file, non ci sono problemi.
#!/bin/bash
im1_dir=(~/prev1/*.png)
im2_dir=(~/prev3/*.png)
exec 3< <(printf '%s\n' "${im1_dir[@]}")
while IFS=$'\n' read -r -u 3 file1; read -r file2
do
run_black "$file1" "$file2"
done < <(printf '%s\n' "${im1_dir[@]}")
exec 3<&-
È possibile effettuare il comportamento coerente in modo che il ciclo si interrompe con i file solo non vuote abbinati indipendentemente da quale elenco è più lungo, sostituendo il punto e virgola con un doppio e commerciale in questo modo:
while IFS=$'\n' read -r -u 3 file1 && read -r file2
Questo versione utilizza un ciclo for
anziché un ciclo while
. Questo si ferma quando il più breve dei due elenchi si esaurisce.
#!/bin/bash
im1_dir=(~/prev1/*.png)
im2_dir=(~/prev3/*.png)
for ((i = 0; i < ${#im1_dir[@]} && i < ${#im2_dir[@]}; i++))
do
run_black "${im1_dir[i]}" "${im2_dir[i]}"
done
Questa versione è simile a quella immediatamente superiore, ma se una delle liste si esaurisce si avvolge intorno a riutilizzare gli oggetti fino a quando l'altra esaurisce. È molto brutto e potresti fare la stessa cosa in un altro modo più semplicemente.
#!/bin/bash
im1_dir=(~/prev1/*.png)
im2_dir=(~/prev3/*.png)
for ((i = 0, j = 0,
n1 = ${#im1_dir[@]},
n2 = ${#im2_dir[@]},
s = n1 >= n2 ? n1 : n2,
is = 0, js = 0;
is < s && js < s;
i++, is = i, i %= n1,
j++, js = j, j %= n2))
do
run_black "${im1_dir[i]}" "${im2_dir[i]}"
done
Questa versione utilizza solo una matrice per il ciclo interno (seconda directory). Verrà eseguito tutte le volte che ci sono file nella prima directory.
#!/bin/bash
im1_dir=~/prev1/*.png
im2_dir=(~/prev3/*.png)
for file1 in $im1_dir
do
run_black "$file1" "${im2_dir[i++]}"
done
Stai cercando il "prodotto cartesiano"? Ad esempio, se la directory 1 ha i file A B C e la directory 2 ha i file a b c, stai cercando i 9 file di output (Aa, Ab, Ac, Ba, Bb, Bc, Ca, Cb, Cc) giusto? – jedwards
@jedwards: Sto pensando che l'OP vuole Aa Bb Cc piuttosto che un prodotto cartesiano. –
@DennisWilliamson: anche a me, ma pensarci troppo mi ha reso incerto – jedwards