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
的变量中,这给出了上述示例的输出:02
和 3
分别。
但是,我很难在不删除前导零的情况下将 +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)}
删除 all 前导零(这是必要的,因为以零为前缀的数字被解释为通过 bash 作为八进制)。
- 函数体包含在圆括号而不是大括号中,因此
shopt -s extglob
的效果是函数调用的局部效果,不会影响调用者的环境。
基于perl
的rename
命令
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 )
使用 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
的变量中,这给出了上述示例的输出:02
和 3
分别。
但是,我很难在不删除前导零的情况下将 +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)}
删除 all 前导零(这是必要的,因为以零为前缀的数字被解释为通过 bash 作为八进制)。- 函数体包含在圆括号而不是大括号中,因此
shopt -s extglob
的效果是函数调用的局部效果,不会影响调用者的环境。
基于perl
的rename
命令
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 )