我在几个文件夹中有几个.jpg文件,实际上大约有20K。文件名不同,如123.jpg,abc.jpg,ab12.jpg。我们需要的是使用前导0模式的bash脚本重命名所有这些文件。
我在下面使用了一个代码,当我这样做时,我每次添加新文件时都会重新重命名以前的文件。任何人都可以帮助我摆脱这种情况,这将是真正的帮助。我已经搜索了整个网络,但找不到一个:(
#!/bin/bash
num=0
for i in *.jpg
do
a=`printf "%05d" $num`
mv "$i" "filename_$a.jpg"
let "num = $(($num + 1))"
done
要提供问题的具体示例,请考虑:
touch foo.jpg bar.jpg baz.jpg
第一次运行此脚本时,bar.jpg
将重命名为filename_00000.jpg
; baz.jpg
已重命名为filename_00001.jpg
; foo.jpg
已重命名为filename_00002.jpg
。这种行为是可以接受的。
如果有人跑了:
touch a.jpg
...然后再次运行脚本,然后将a.jpg
重命名为filename_00000.jpg
,重命名filename_00000.jpg
(现在为a.jpg
,旧版本被覆盖!) filename_00001.jpg
,将filename_00001.jpg
重命名为filename_00002.jpg
,等等。
如何让程序单独保留与filename_#####.jpg
匹配的文件,并将新文件重命名为最后一个已存在的数字?
答案 0 :(得分:1)
#!/bin/bash
shopt -s extglob # enable extended globbing -- regex-like syntax
prefix="filename_"
# Find the largest-numbered file previously renamed
num=0 # initialize counter to 0
for f in "$prefix"+([[:digit:]]).jpg; do # Iterate only over names w/ prefix/suffix
f=${f#"$prefix"} # strip the prefix
f=${f%.jpg} # strip the suffix
if (( 10#$f > num )); then # force base-10 evaluation
num=$(( 10#$f ))
fi
done
# Second pass: Iterate over *all* names, and rename the ones that don't match the pattern
for i in *.jpg; do
[[ $i = "$prefix"+([[:digit:]]).jpg ]] && continue # Skip files already matching pattern
printf -v a '%05d' "$num" # More efficient than subshell use
until mv -n -- "$i" "$prefix$a.jpg"; do # "--" forces parse of "$i" as name
[[ -e "$i" ]] || break # abort if source file disappeared
num=$((num + 1)) # if we couldn't rename, increment num
printf -v a '%05d' "$num" # ...and try again with the next name
done
num=$((num + 1)) # modern POSIX math syntax
done
请注意使用mv -n
来防止覆盖 - 这样,同时运行此脚本的两个副本不会覆盖彼此'文件。