ここでは、長所と短所に関するメモを使用して、探していることを行うためのいくつかの追加の方法を示します.
以下は、改行を含まないファイル名でのみ機能します。ファイルをロックステップでペアリングします。追加のファイル記述子を使用して、最初のリストから読み取ります。さらにファイル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<&-
次のようにセミコロンを 2 つのアンパサンドに置き換えることで、どちらのリストが長くても、一致する空でないファイルのみでループが停止するように動作を一貫させることができます。
while IFS=$'\n' read -r -u 3 file1 && read -r file2
このバージョンでは、for
ループの代わりにループを使用しwhile
ます。これは、2 つのリストのうち短い方がなくなると停止します。
#!/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
このバージョンはすぐ上のものと似ていますが、リストの 1 つがなくなると、他のリストがなくなるまでアイテムを再利用するために循環します。それは非常に醜く、同じことを別の方法でもっと簡単に行うことができます。
#!/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
このバージョンは、内側のループ (2 番目のディレクトリ) に配列のみを使用します。最初のディレクトリにあるファイルの数だけ実行されます。
#!/bin/bash
im1_dir=~/prev1/*.png
im2_dir=(~/prev3/*.png)
for file1 in $im1_dir
do
run_black "$file1" "${im2_dir[i++]}"
done