shell 如何在bash中对任意长度的编号、分隔字母数字字符串的文件名进行零填充?

6kkfgxo0  于 12个月前  发布在  Shell
关注(0)|答案(1)|浏览(130)

我正在寻找一种优雅的CLI方法来零填充文件名,这些文件名是任意长度的编号字母数字字符串,并且用破折号代替空格。
例如,我想要以下文件列表:

1-file-name-of-one-length.mp3
2-shorter-file-name.mp3
3-really-really-really-long-file-name.mp3
> ..
10-another-file-name.mp3

成为:

01-file-name-of-one-length.mp3
02-shorter-file-name.mp3
03-really-really-really-long-file-name.mp3
> ..
10-another-file-name.mp3

我花了一天的时间学习awk、bash和重命名零填充方法,但我发现之前的问题和教程似乎假设一个纯数字或标准长度的文件命名方案。在这种情况下,分隔符之间的字段可以被分解并且以可预测的方式重新组装,例如,awk。我的字符串长度未知,因此在'-'字符之间包含未知数目的字段。
我设想答案将是“for循环”。我希望循环执行的逻辑如下:读取文件名到第一个“-”字符。确定第一个“-”前面的数字是个位数还是两位数。如果是个位数,请在其前面插入“0”字符。

编辑答案

Renaud指出了一个简单for循环的正确语法(我自己沿着这些行的尝试也导致了两位数的填充,但Renaud的代码工作了)
对于f在[0-9]-*.mp3中; do mv“$f”“0$f”;做

ahy6op9u

ahy6op9u1#

要仅填充一个0,请执行以下操作:

for f in [0-9]-*.mp3; do mv "$f" "0$f"; done

如果没有匹配[0-9]-*.mp3模式的文件,最好也使用nullglob选项(在子shell中,只是为了之后自动恢复nullglob状态):

( shopt -s nullglob; for f in [0-9]-*.mp3; do mv "$f" "0$f"; done )

如果你想要n位的前导数字而不是2,比如3:

(
n=3
shopt -s extglob nullglob
for f in +([0-9])-*.mp3; do
  printf -v g '%0*d-%s' "$n" "${f%%-*}" "${f#*-}"
  mv "$f" "$g"
done
)

最后,如果你不知道n的值,想自动计算它,并假设它必须是这些文件名中前导数字的最大数量:

(
shopt -s extglob nullglob
n=0
for f in +([0-9])-*.mp3; do
  g="${f%%-*}"
  (( n = "${#g}" > n ? "${#g}" : n ))
done
for f in +([0-9])-*.mp3; do
  printf -v g '%0*d-%s' "$n" "${f%%-*}" "${f#*-}"
  mv "$f" "$g"
done
)

相关问题