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



对于Linux,我想在使用的格式中自动添加Oracle DB表空间。要做到这一点,我想做一个+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到$counter,而不删除前导零(02应该是下一个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)}就会删除所有前导零(这是必要的,因为以零为前缀的数字会被bash解释为八进制)。
  • 函数体用圆括号而不是大括号括起来,这样shopt -s extglob的效果对函数调用是局部的,不会影响调用者的环境。

使用基于perlrename命令

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

rename命令的-n选项允许在实际重命名

之前运行一个干测试


样品测试

$ rename -n 's/0*Kd+(?=.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为三位数格式,等等…

try

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

最新更新