這裏有一些額外的方式來做你要找的利弊注意事項。
以下僅適用於不包含換行符的文件名。它以鎖步方式將文件配對。它使用額外的文件描述符從第一個列表中讀取。如果im1_dir
包含更多文件,則當im2_dir
用完時,循環將停止。如果im2_dir
包含更多文件,則file1
對於所有不匹配的file2
將爲空。當然,如果它們包含相同數量的文件,則沒有問題。
#!/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<&-
可以使行爲是一致的,這樣的循環,只有非空匹配的文件停止無論哪個名單不再由具有雙符號代替分號像這樣:
while IFS=$'\n' read -r -u 3 file1 && read -r file2
這版本使用for
循環而不是while
循環。當兩個列表中的較短者耗盡時,這個停止。
#!/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
這個版本是一個類似於正上方,但如果列表中的一個用完它環繞直到另一個用完再利用的項目。這是非常醜陋的,你可以更簡單地以另一種方式做同樣的事情。
#!/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
此版本僅爲內部循環(第二個目錄)使用數組。它只會執行與第一個目錄中的文件相同的次數。
#!/bin/bash
im1_dir=~/prev1/*.png
im2_dir=(~/prev3/*.png)
for file1 in $im1_dir
do
run_black "$file1" "${im2_dir[i++]}"
done
您是否在尋找「笛卡爾產品」?例如,如果目錄1包含文件A B C,而目錄2包含文件a b c,那麼您正在尋找9個輸出文件(Aa,Ab,Ac,Ba,Bb,Bc,Ca,Cb,Cc)嗎? – jedwards
@jedwards:我在想OP是想要Aa Bb Cc而不是笛卡爾產品。 –
@丹尼斯威廉姆森:我也是,但考慮太多讓我不確定 – jedwards