如何在shell脚本中迭代两组可迭代对象?

ixt*_*lix 4 shell-script

通常,当我为特定任务编写 shell 脚本时,我只制作一个文件列表,如下所示:

#/bin/sh
read -d '' imagefiles <<EOF

./01/IMG0000.jpg
./01/IMG0001.jpg
./01/IMG0002.jpg
./01/IMG0003.jpg
./01/IMG0004.jpg
./01/IMG0005.jpg
./01/IMG0006.jpg
./01/IMG0007.jpg
(a whole bunch of files down to ./10/IMG0102.jpg)

EOF

for i in $imagefiles
  for j in range(len(commands))
do

mv $i ./$j.jpg

  done
done
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望能够迭代输出,seq但按照 Gilles 的建议简单地将该部分作为 Python 写出来(是的,我知道它会执行每个命令 j 次,导致大约 100000 次执行) . 当天早些时候,我按顺序重命名了 736 个文件,但现在我重命名了 1000 个文件。我确信有更好的方法来做到这一点(请不要犹豫告诉我),但知道如何迭代命令列表和其他一些可迭代对象仍然很好。

Gil*_*il' 5

好的,所以您想要压缩两个可迭代对象,或者换句话说,您想要一个循环,迭代一堆字符串,并带有一个额外的计数器。实现计数器非常容易。

n=0
for x in $commands; do
  mv -- "$x" "$n.jpg"
  n=$(($n+1))
done
Run Code Online (Sandbox Code Playgroud)

请注意,这仅在您迭代的元素都不包含任何空格(或通配符)时才有效。如果您有由换行符分隔的项目,请关闭通配符并仅在换行符上拆分。

n=0
IFS='
'; set -f
for x in $commands; do
  mv -- "$x" "$n.jpg"
  n=$(($n+1))
done
set +f; unset IFS
Run Code Online (Sandbox Code Playgroud)

如果您只需要对数据进行一次迭代,请循环read(有关更多解释请参阅为什么while IFS= read如此频繁地使用,而不是IFS=; while read..?)。

n=0
while IFS= read -r x; do
  mv -- "$x" "$n.jpg"
  n=$(($n+1))
done <<EOF
…
EOF
Run Code Online (Sandbox Code Playgroud)

如果您使用具有数组(bash、ksh 或 zsh)的 shell,请将元素存储在数组中。在 zsh 中,要么运行setopt ksh_arrays从 0 开始对数组元素进行编号,要么修改代码以从 1 开始对数组元素进行编号。

commands=(
    ./01/IMG0000.jpg
    …
)
n=0
while [[ $n -lt ${#commands} ]]; do
  mv -- "${commands[$n]}" "$n.jpg"
done
Run Code Online (Sandbox Code Playgroud)