在文件和文件夹的名称中递归填充 0
Recursively padding 0's in names of files and folders
我有一个文件夹,其中包含关于某个特定主题的视频讲座。它的结构如下:
.
├── 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,但它相当 lengthy 和 slow:
find . -depth -exec rename -v 's/(.*)\/([0-9]$)/\/00/;
s/(.*)\/([0-9]{2}$)/\/0/;
s/(.*)\/([0-9][^0-9][^\/]*$)/\/00/;
s/(.*)\/([0-9]{2}[^0-9][^\/]*$)/\/0/' '{}' ';'
这可以进一步优化吗?
编辑
实际上,在';'之后执行变得非常快已更改为“+”。但是这组正则表达式看起来仍然很难看。
rename
是一个 perl 工具,允许您使用任何 perl 表达式。以下 perl 表达式搜索路径的最后一个组成部分(例如 a/b/c
中的 c
)并将其前导数字(如果存在)填充为三位数字。
s/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/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
命令中使用上面的 perl 表达式 bash
* ...
find -depth -exec rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/ge' {} +
...或 zsh
中的扩展 globstar 功能。在我的系统上,globs 比 find
.
快
rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/ge' **/*(On)
**/*
递归列出所有文件和目录,(On)
颠倒顺序类似于 -depth
。
✱ 对于 bash
你仍然可以使用 **/*
和 shopt -s globstar
但是颠倒匹配文件的顺序并不那么容易,所以 find
更简单并且可能快点。
我有一个文件夹,其中包含关于某个特定主题的视频讲座。它的结构如下:
.
├── 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,但它相当 lengthy 和 slow:
find . -depth -exec rename -v 's/(.*)\/([0-9]$)/\/00/;
s/(.*)\/([0-9]{2}$)/\/0/;
s/(.*)\/([0-9][^0-9][^\/]*$)/\/00/;
s/(.*)\/([0-9]{2}[^0-9][^\/]*$)/\/0/' '{}' ';'
这可以进一步优化吗?
编辑
实际上,在';'之后执行变得非常快已更改为“+”。但是这组正则表达式看起来仍然很难看。
rename
是一个 perl 工具,允许您使用任何 perl 表达式。以下 perl 表达式搜索路径的最后一个组成部分(例如 a/b/c
中的 c
)并将其前导数字(如果存在)填充为三位数字。
s/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/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
命令中使用上面的 perl 表达式 bash
* ...
find -depth -exec rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/ge' {} +
...或 zsh
中的扩展 globstar 功能。在我的系统上,globs 比 find
.
rename 's/(^|\/)\K(\d+)(?=[^\/]*$)/sprintf "%03d",/ge' **/*(On)
**/*
递归列出所有文件和目录,(On)
颠倒顺序类似于 -depth
。
✱ 对于 bash
你仍然可以使用 **/*
和 shopt -s globstar
但是颠倒匹配文件的顺序并不那么容易,所以 find
更简单并且可能快点。