如何将数字标题文件名重命名为 1 位数字?

如何将数字标题文件名重命名为 1 位数字?

这感觉很简单,但我完全被难住了。不用说我对此完全陌生。我有一个目录,其中的文件编号从000020。我想通过添加 1 来重命名这些文件,以便000成为001等。理想情况下使用awk命令,但任何建议将不胜感激,谢谢。

没有前缀,000是整个名称。没有标记为 的文件021

答案1

使用zsh代替bash,你可以这样做:

autoload -Uz
zmv -f -n '*(#qnOn)' '${f//(#m)<->/${(l[3][0])$((MATCH+1))}}'

将当前目录中的文件名中的每个数字增加并用 0 填充它们的长度,使其长度为 3。例如foo-1-2-003.ext重命名为foo-002-003-004.ext或。012013

(如果整个文件是一个数字,那就zmv -f -n '<->(#qnOn)' '${(l[3][0])$((MATCH+1))}'足够了,或者<0-20><->重命名0到20之间的文件,或者<0-20>~^[0-9](#c3)用3位数字表示的0到20之间的文件)。

替换是使用ksh-style计算的${var//pattern/replacement},模式为(#m)<->(#m)以触发捕获匹配的内容$MATCH<->匹配任何十进制数字序列( 的无界形式<3-12>)。 left l[width][pad]-padding 参数扩展标志用于填充。

我们使用和限定符按其名称的反向n数字顺序对文件列表进行排序,以确保重命名为之前重命名为。OnnOn qfile002file003file001file002

禁用健全性检查,这里会抱怨在源中也找到了一些目的地,但这意味着如果同时存在 a和文件,-f它不会防止数据丢失。file1file01

如果您没有 zsh,但有 bash 和名为 000 到 020 的文件存在,并且是您想要重命名的文件(如您稍后澄清的那样),您可以执行以下操作:

for file in {020..000}; do
  printf -v new %03d "$(( 10#$file + 1 ))"
  mv "$file" "$new"
done

{020..000}(bash实际上是从 zsh 复制的,而 zsh-v从 bash 复制的,该代码在两个 shell 中都可以工作;10#和 引号在 中不是必需的zsh)。

在这里,由于文件名非常驯服,您还可以执行以下操作:

ls -rq | LC_ALL=C awk '
  /^[0-9]{3}$/ && $0 <= 20 {
    printf "mv %s %03d\n", $0, $0+1
  }' | sh

-q(标准,但目前 busybox 不支持ls)以确保每一行有一个文件名,即使存在名称中包含换行符的文件。LC_ALL=C所以[0-9]只匹配0123456789.如果awkmawk,请替换[0-9]{3}[0-9][0-9][0-9].

答案2

如果没有间隙,例如 logrotate 文件,那么 ls 可以为您完成工作,不需要 math / awk :

dest=021; ls -r|while read file; do mv $file $dest; dest=$file; done

如果 dest 不总是 021,那么类似 dest=$(printf "%03d" $(ls|wc -l))

相关内容