这里有一些额外的方法来做你正在寻找的关于利弊的注释。
以下仅适用于不包含换行符的文件名。它以同步方式配对文件。它使用额外的文件描述符从第一个列表中读取。如果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