Linux Bash 文件名自动编号而不删除前导零

Linux Bash autonumbering of filenames without removing leading zero

使用 Linux 我想在使用的格式中自动添加 Oracle 数据库表空间。为此,我想与上一个文件相比增加 +1。

数据文件通常以这种格式调用:

/ora/oradata/tablespace_datafile.dbf
/ora/oradata/tablespace_datafile_02.dbf
/ora/oradata/tablespace_datafile_3.dbf

我能够将 $basefilename 提取到具有 sed 's/[0-9].*// 的变量中,输出为:/ora/oradata/tablespace_datafile_

我还能够将带有 sed s/[^0-9]//g 的数字提取到应该是 $counter 的变量中,这给出了上述示例的输出:023分别。

但是,我很难在不删除前导零的情况下将 +1 添加到 $counter02 应该是下一个 03,但相反,我得到 3。我正在使用 let counter++

当前代码:

basefilename=`echo $connectdb | sed 's/[0-9].*//'`
counter=`echo $connectdb | sed 's/[^0-9]//g'`
let counter++
nextdatafilename=$basefilename$counter'.dbf'

有什么建议吗?

此 bash 函数将增加其数字参数,并根据需要保留前导零(请注意,${parameter##word} 参数扩展语法会混淆语法突出显示):

inc() ( shopt -s extglob; printf "%0${#1}d" $((${1##+(0)} + 1)) )

示例:

$ echo $(inc 1)
2
$ echo $(inc 01)
02
$ echo $(inc 001)
002
$ echo $(inc 09)
10
$ echo $(inc 009)
010
$ echo $(inc 0)
1

根据您的情况使用它:

nextdatafilename="$basefilename$(inc $counter).dbf"

解释:

  • printf "%0${#1}d" 使用至少与参数包含的数字一样多的数字来格式化结果
  • shopt -s extglob 启用扩展模式匹配,以便扩展 ${1##+(0)} 删除 all 前导零(这是必要的,因为以零为前缀的数字被解释为通过 bash 作为八进制)。
  • 函数体包含在圆括号而不是大括号中,因此 shopt -s extglob 的效果是函数调用的局部效果,不会影响调用者的环境。

基于perlrename命令

rename -n 's/0*\K\d+(?=\.dbf)/$&+1/e' *.dbf
  • 0*\K 忽略前导零
  • \d+ 匹配数字
  • (?=\.dbf) 假定数字以 OP 中提到的文件扩展名结尾,这确保数字在其他任何地方都不匹配。如果不需要可以删除
  • $&+1 将匹配的数字加一
  • /e 这个修饰符允许在替换部分使用表达式而不是字符串

rename 命令的 -n 选项允许在实际重命名之前 运行 干测试


样本测试

$ rename -n 's/0*\K\d+(?=\.dbf)/$&+1/e' tst/*.dbf
rename(tst/abc_01.dbf, tst/abc_02.dbf)
rename(tst/aef_2.dbf, tst/aef_3.dbf)


如果 09 必须更改为 10 而不是 010

$ rename -n 's/\d+(?=\.dbf)/sprintf "%02d", $&+1/e' tst/*.dbf
rename(tst/abc_01.dbf, tst/abc_02.dbf)
rename(tst/aef_09.dbf, tst/aef_10.dbf)

%02d 更改为 %03d 以进行三位数格式等...

尝试

nextdatafilename=$( printf "%s%02d.dbf" $basefilename $counter )