我有一个 bash 脚本,它根据命令提示符的输入重命名文件夹中的文件:
echo "Please rename and press enter" read rename
if [ -z "$rename" ]; then
printf "no caption was selected, aborting!\n"
exit 1
fi
printf "rename is $rename\n" count=1
for i in *.jpg; do
j=printf "%04d" $count
j="$rename"$j".jpg"
count=$((count + 1))
mv "$i" $j
done
fi
shift
done
Run Code Online (Sandbox Code Playgroud)
如何修改此脚本,以便根据文件大小重命名文件夹中的文件?
如果我根据大小对文件进行排序,它们在文件夹中将如下所示:
a009 978kb
a001 567kb
a003 499kb
a008 432kb
Run Code Online (Sandbox Code Playgroud)
所以我想重命名生成的文件:
a001 978kb
a002 567kb
a003 499kb
a004 432kb
Run Code Online (Sandbox Code Playgroud)
像这样的东西:
echo "Please rename and press enter"
read rename
ls |
# prepend filename with file size in bytes
parallel stat -c %s,,sep,,%n -- |
# sort by number
sort -n |
# rename to sequencenumber followed by size in bytes
parallel -q --colsep ,,sep,, mv {2} "$rename"{#}_{1}
Run Code Online (Sandbox Code Playgroud)
主要技巧是替换
for i in *.jpg
Run Code Online (Sandbox Code Playgroud)
和
for i in $(ls -S *.jpg)
Run Code Online (Sandbox Code Playgroud)
然而,正如 Kusalananda 所指出的,这假定了“受过教育的”文件名(没有空格,没有控制字符),所以这里有一种不同的方法:
count=1
ls -S --escape *.jpg | while read f; do
n=$(printf "%04d" $count)
((count++))
mv --no-clobber "$f" "$rename$n.jpg"
done
Run Code Online (Sandbox Code Playgroud)
-S
按减小文件大小进行排序
--escape
防止嵌入换行符的名称造成损坏
--no-clobber
防止在脚本运行两次时覆盖目标文件
PS Ole Tange 的答案是一种非常有效的方法,可以完成相同的任务,但除非您经常重命名数千个文件,否则您可能不会看到差异。