通常,当我为特定任务编写 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
在本例中,我希望能够迭代 的输出seq
,但按照 Gilles 的建议,只需将这部分写为 Python(是的,我知道它会执行每个命令 j 次,导致大约 100000 次执行) 。当天早些时候,我按顺序重命名了 736 个文件,但现在我要重命名 1000 多个文件。我确信有更好的方法可以做到这一点(请毫不犹豫地告诉我),但是知道如何迭代命令列表和其他一些可迭代的内容仍然会很高兴。
答案1
好的,所以您想要压缩两个可迭代对象,或者换句话说,您想要一个循环,迭代一堆字符串,并带有一个附加计数器。实现计数器非常容易。
n=0
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
请注意,只有当您要迭代的元素都不包含任何空格(也不包含通配符)时,这才有效。如果您的项目由换行符分隔,请关闭通配符并仅在换行符上拆分。
n=0
IFS='
'; set -f
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
set +f; unset IFS
如果您只需要迭代数据一次,请循环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
如果您使用的 shell 具有数组(bash、ksh 或 zsh),请将元素存储在数组中。在 zsh 中,要么运行setopt ksh_arrays
从 0 开始对数组元素进行编号,要么调整代码以从 1 开始对数组元素进行编号。
commands=(
./01/IMG0000.jpg
…
)
n=0
while [[ $n -lt ${#commands} ]]; do
mv -- "${commands[$n]}" "$n.jpg"
done
答案2
如果您的 shell 是bash
,则无需运行该seq
程序。只需使用
for i in {1..736}
do
如果您想要一个带有前导零的序列,只需使用{001..736}
(甚至{0001..0736}
) 即可。
另外,如果可能的话,尽量不要使用反引号(请参阅这个问题,了解它如何把事情搞砸)。
另一件事是,当您想要操作一组文件时,您可能会发现这很有用:
for file in /some/path/*
do
它将对所有文件进行操作(和文件夹)在目录中/some/path/
。要将范围缩小到仅文件,您可以使用类似的测试[ -f "$file" ]
,例如
for file in /some/path/*
do
[ -f "$file" ] || continue
(do your stuff here)
此外,该构造可以通过、等/some/path/*
shell 模式进行调整。/some/path[123]/*
/some/path[A-Z]/b*[e-g]*
/some/path{1,5,23}/*
就问题的第一部分而言,您可以使用嵌套for
(或while
任何)循环,如下所示:
for cm in $commands; do
for file in /some/path[ab]{1,4,2}/*.log; do
mv "${file}" "${file//text/replacement}"
done
done
答案3
我不认为你可以在 bash 中并行迭代多个事物。
我会开始i=1
。然后迭代文件列表并包含let i=$i+1
在循环中。$i -ge 736
如果您想在循环次数之后停止对输入的任何内容进行迭代,还包括一个跳出循环的测试。
i=0
for file in ./{01..10}/*jpg; do
let i=$i+1
mv "$file" "$i-$file"
done
如果您尝试关闭 X 个文件,您可以使用如下测试:
[[ $i -ge 736 ]] && return || let i=$i+1
答案4
bash 支持数组:
http://tldp.org/LDP/abs/html/arrays.html
或者
COUNT=0
for i in `ls *.txt`
do
COUNT=`expr $COUNT + 1`
mv "$i" "$COUNT-$i"
done
这会将文件 a.txt b.txt c.txt 重命名为 1-a.txt 2-b.txt 3-c.txt。