在文件和文件夹的名称中递归填充0'

时间:2018-10-04 10:16:36

标签: linux bash rename zsh pad

我有一个文件夹,其中包含有关某些特定主题的视频讲座。它的结构如下:

.
├── 1_fol
│   ├── 1_file.mp4
│   ├── 2_file.mp4
│   └── 3_file.mp4
└── 2_fol
    ├── 10_file.mp4
    ├── 4_file.mp4
    ├── 5_file.mp4
    ├── 6_file.mp4
    ├── 7_file.mp4
    ├── 8_file.mp4
    └── 9_file.mp4

我想将此结构更改为

.
├── 001_fol
│   ├── 001_file.mp4
│   ├── 002_file.mp4
│   └── 003_file.mp4
└── 002_fol
    ├── 004_file.mp4
    ├── 005_file.mp4
    ├── 006_file.mp4
    ├── 007_file.mp4
    ├── 008_file.mp4
    ├── 009_file.mp4
    └── 010_file.mp4

这很有帮助,因为您随后可以使用find . -regextype sed -regex ".*/.*\.\(mp3\|mp4\)" -print0 | sort -z | xargs -r0 vlc打开整个播放列表。我想出了一个填充0的脚本,但它很长

find . -depth -exec rename -v 's/(.*)\/([0-9]$)/$1\/00$2/;
      s/(.*)\/([0-9]{2}$)/$1\/0$2/;
      s/(.*)\/([0-9][^0-9][^\/]*$)/$1\/00$2/;
      s/(.*)\/([0-9]{2}[^0-9][^\/]*$)/$1\/0$2/' '{}' ';'

这可以进一步优化吗?

修改
实际上,';'之后执行变得非常快。已更改为“ +”。但是正则表达式集仍然看起来很丑。

1 个答案:

答案 0 :(得分:2)

rename是一个perl工具,可让您使用任何perl表达式。以下perl表达式搜索路径的最后一部分(例如c中的a/b/c),并将其前导号(如果存在)填充到三位数。

s/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",$2/e

示例:

  • 1_fol/23_file.mp4成为1_fol/023_file.mp4
  • 1_fol成为001_fol
  • 1_2/3_4.mp4成为1_2/003_4.mp4
  • 1_2成为001_2

find✱中的bash命令中使用上述perl表达式...

find -depth -exec rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",$2/ge' {} +

...或zsh中的扩展globstar功能。在我的系统上,全局速度比find快。

rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",$2/ge' **/*(On)

**/*递归列出所有文件和目录,(On)颠倒顺序类似于-depth

✱对于bash,您仍然可以将**/*shopt -s globstar一起使用,但是反转匹配文件的顺序并不那么容易,因此find更简单,而且可能更快。