Рекурсивное заполнение нулями в именах файлов и папок

У меня есть папка с видео лекциями по определенной теме. Это структурировано так:

.
├── 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 ответ

Решение

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

Используйте выше выражение perl в вашем find команда для bash✱...

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

... или расширенные возможности Globstar в zsh, В моей системе глобусы были быстрее, чем find,

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

**/* рекурсивно перечисляет все файлы и каталоги и (On) меняет порядок, аналогичный -depth,

✱ Для bash ты еще мог бы использовать **/* с shopt -s globstar но изменить порядок сопоставления файлов не так просто, поэтому find Это проще и, вероятно, быстрее.

Другие вопросы по тегам