关于重命名:如何在Bash文件名中填充数字?

关于重命名:如何在Bash文件名中填充数字?

How to zero pad numbers in file names in Bash?

使用Bash重命名表单中文件的最佳方法是什么:

1
(foo1, foo2, ..., foo1300, ..., fooN)

使用零填充文件名:

1
(foo00001, foo00002, ..., foo01300, ..., fooN)

它不是纯粹的bash,但使用rename命令更容易:

1
rename 's/\d+/sprintf("%05d",$&)/e' foo*

如果N不是先验固定的:

1
 for f in foo[0-9]*; do mv $f `printf foo%05d ${f#foo}`; done


我有一个更复杂的案例,文件名有一个后缀和一个前缀。我还需要对文件名中的数字进行减法。

例如,我希望foo56.webp成为foo00000055.webp

我希望如果你做的事更复杂,这会有所帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

prefix="foo"
postfix=".webp"
targetDir="../newframes"
paddingLength=8

for file in ${prefix}[0-9]*${postfix}; do
  # strip the prefix off the file name
  postfile=${file#$prefix}
  # strip the postfix off the file name
  number=${postfile%$postfix}
  # subtract 1 from the resulting number
  i=$((number-1))
  # copy to a new name with padded zeros in a new folder
  cp ${file}"$targetDir"/$(printf $prefix%0${paddingLength}d$postfix $i)
done

我使用的oneline命令是这样的:

1
ls * | cat -n | while read i f; do mv"$f" `printf"PATTERN""$i"`; done

PATTERN可以是例如:

  • 使用增量计数器重命名:%04d.${f#*.}(保留原始文件扩展名)
  • 使用前缀为photo_%04d.${f#*.}的增量计数器重命名(保留原始扩展名)
  • 使用增量计数器重命名并将扩展名更改为jpg:%04d.webp
  • 使用带有前缀和文件basename的增量计数器重命名:photo_$(basename $f .${f#*.})_%04d.${f#*.}
  • ...

您可以使用例如ls *.webp | ...过滤要重命名的文件

您可以使用作为文件名的变量f和作为计数器的i

对于您的问题,正确的命令是:

1
ls * | cat -n | while read i f; do mv"$f" `printf"foo%d05""$i"`; done

Pure Bash,除了'mv'之外没有任何外部进程:

1
2
3
4
5
for file in foo*; do
  newnumber='00000'${file#foo}      # get number, pack with zeros
  newnumber=${newnumber:(-5)}       # the last five characters
  mv $file foo$newnumber            # rename
done

以下将这样做:

1
for ((i=1; i<=N; i++)) ; do mv foo$i `printf foo%05d $i` ; done

编辑:改为使用((i = 1,...)),谢谢mweerden!


对于文件名中的左键数字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 1.zzz

$ for f in [0-9]*.[a-z]*; do tmp=`echo $f | awk -F. '{printf"%04d.%s
", $1, $2}'
`; mv"$f""$tmp"; done;

$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0001.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10

说明

1
2
3
for f in [0-9]*.[a-z]*; do tmp=`echo $f | \
awk -F. '{printf"%04d.%s
", $1, $2}'
`; mv"$f""$tmp"; done;
  • 注意反引号:`echo ... $2}\`(反斜杠,,上面只是为了便于阅读而将单行分为两行)
  • 在循环中查找名为具有小写字母扩展名的数字的文件:[0-9]*.[a-z]*
  • 回显该文件名($f)以将其传递给awk
  • -F.awk字段分隔符,句点(.):如果匹配,则将文件名分隔为两个字段($1 = number; $2 = extension)
  • 格式为printf:将第一个字段($1,数字部分)打印为4位数(%04d),然后打印句点,然后将第二个字段($2:扩展名)打印为字符串(< X40>)。所有这些都分配给$tmp变量
  • 最后,将源文件($f)移动到新文件名($tmp)

我的解决方案替换了字符串中的数字

1
2
3
4
5
for f in * ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf"%04d" $number`
    echo $f | sed"s/${number}/${padded}/";
done

您可以轻松地尝试它,因为它只打印转换后的文件名(不执行文件系统操作)。

说明:

循环遍历文件列表

循环:for f in * ; do ;done,列出所有文件,并将每个文件名作为$f变量传递给循环体。

从字符串中抓取数字

使用echo $f | sed,我们将变量$f传递给sed程序。

在命令sed 's/[^0-9]*//g'中,带有修饰符^的部分[^0-9]*表示与数字0-9(不是数字)相反,然后用空替换//将其删除。为什么不删除[a-z]?因为文件名可以包含点,破折号等。所以,我们剥离所有东西,这不是数字并得到一个数字。

接下来,我们将结果分配给number变量。请记住不要在分配中放置空格,例如number = …,因为你会得到不同的行为。

我们将命令的执行结果分配给变量,用反引号符号`包装命令。

零填充

命令printf"%04d" $number将数字的格式更改为4位,如果我们的数字少于4位,则添加零。

将数字替换为零填充数字

我们再次使用sed替换命令,如s/substring/replacement/。为了解释我们的变量,我们使用双引号并以这种方式替换我们的变量${number}

上面的脚本只打印转换后的名称,所以,让我们做实际的重命名工作:

1
2
3
4
5
6
for f in *.js ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf"%04d" $number`
    new_name=`echo $f | sed"s/${number}/${padded}/"`
    mv $f $new_name;
done

希望这有助于某人。

我花了几个小时来解决这个问题。


这是一个快速的解决方案,假设一个固定长度前缀(您的"foo")和固定长度填充。如果您需要更多的灵活性,这可能至少是一个有用的起点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

# some test data
files="foo1
foo2
foo100
foo200
foo9999"


for f in $files; do
    prefix=`echo"$f" | cut -c 1-3`        # chars 1-3 ="foo"
    number=`echo"$f" | cut -c 4-`         # chars 4-end = the number
    printf"%s%04d
"
"$prefix""$number"
done

推荐阅读

    linux命令重命名配置?

    linux命令重命名配置?,图片,名称,名字,文件,软件,代码,命令,文件名,脚本,批

    linux命令交换文件名?

    linux命令交换文件名?,命令,文件,数据,名称,工具,地址,软件,系统,基础知识,

    linux复制命令重命名?

    linux复制命令重命名?,系统,命令,文件,目录,百度,管理,人员,设计,名字,主体,L

    linux排序数字命令?

    linux排序数字命令?,标准,数字,单位,情况,系统,信息,命令,文件,顺序,参数,lin

    linux命令不能打数字?

    linux命令不能打数字?,工作,密码,数字,地址,电脑,系统,命令,设备,下来,预期,

    linux查找文件名命令?

    linux查找文件名命令?,系统,信息,工具,命令,文件,字符串,样式,管道,文本,动

    linux中命令重命名?

    linux中命令重命名?,软件,名字,文件,命令,系统,工具,文件名,目录,指令,源文

    linux打印文件名命令?

    linux打印文件名命令?,系统,工作,管理,命令,信息,标准,工具,预期,目录,文件,L

    linux命令修改文件名?

    linux命令修改文件名?,系统,名字,软件,文件,命令,位置,状态,工具,文件名,目

    linux重命名命令详解?

    linux重命名命令详解?,名字,软件,文件,状态,命令,文件名,指令,目录,源文件,

    linux中的重命名命令?

    linux中的重命名命令?,系统,软件,名字,位置,命令,文件,工具,环境,目录,文件

    linux系统命令重命名?

    linux系统命令重命名?,系统,软件,名字,位置,文件,命令,状态,工具,文件名,目

    linux生成数字命令?

    linux生成数字命令?,密码,数字,设备,环境,名称,时间,单位,地址,信息,系统,求

    linux创建文件名命令?

    linux创建文件名命令?,名字,文件,命令,文件名,系统,密码,终端,目录,符号,文

    linux命令搜索文件名?

    linux命令搜索文件名?,系统,工具,信息,名称,命令,文件,标准,字符串,文件名,

    linux显示文件名命令?

    linux显示文件名命令?,信息,时间,命令,系统,数据,地址,状态,文件,标准,工具,L

    linux中改文件名命令?

    linux中改文件名命令?,名字,命令,文件,软件,位置,系统,文件名,目录,目标,选