Рекурсивное заполнение нулями в именах файлов и папок - PullRequest
0 голосов
/ 04 октября 2018

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

.
├── 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 голосов
/ 04 октября 2018

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 проще и, вероятно, быстрее.

...