根据大小重命名文件的 Bash 脚本

根据大小重命名文件的 Bash 脚本

我有一个 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

如何修改此脚本,以便文件夹中的文件根据其大小重命名?

如果我根据大小对文件进行排序,它们在文件夹中将如下所示:

a009      978kb
a001      567kb
a003      499kb
a008      432kb

所以我想重命名生成的文件:

a001      978kb
a002      567kb
a003      499kb
a004      432kb

答案1

像这样的东西:

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}

答案2

主要技巧是替换

    for i in *.jpg

    for i in $(ls -S *.jpg)

然而,正如 Kusalananda 指出的那样,这假定了“受过教育的”文件名(没有空格,没有控制字符),所以这里有一种不同的方法:

count=1
ls -S --escape *.jpg | while read f; do
    n=$(printf "%04d" $count)
    ((count++))
    mv --no-clobber "$f" "$rename$n.jpg"
done

-S按减小文件大小进行排序
--escape防止嵌入换行符的名称造成损坏
--no-clobber防止在脚本运行两次时覆盖目标文件

PS Ole Tange 的答案是一种非常有效的方法来完成相同的任务,但除非您经常重命名数千个文件,否则您可能不会看到差异。

答案3

zsh外壳中:

typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "a$count.jpg"
done

.jpg这将按照从最大到最小的顺序迭代当前目录中具有文件名后缀的所有常规文件。对于每个文件,它会将其重命名为到目前为止已处理的文件的零填充整数计数aNNN.jpgNNN

glob限定符使用(“按长度反转顺序”)(.DNOL)以正确的顺序对匹配的文件名进行排序,并使用(“常规文件和点文件”)仅选择常规文件(包括隐藏名称)。如果没有匹配的名称(“null glob”),则会使模式扩展为空。OL.DN

这适用于任何zsh已安装的 Unix 系统上的所有有效文件名。

要使用它bash

zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "a$count.jpg"
done'

如果您想将变量$rename作为文件名前缀传递,而不是使用a

zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "$1$count.jpg"
done' zsh "$rename"

请注意,zsh最后一行的 不是拼写错误,并且 的值在脚本内$rename使用。$1zsh -c

相关内容