Массовое переименование файлов внутри подпапки с удалением префикса

гну сэд:

$ s='"dfs.datanode.data.dir" : "/rid/sdb/oo/hdfs/data,/rid/sdc/oo/hdfs/data,/rid/sdd/oo/hdfs/data,/rid/sde/oo/hdfs/data,/rid/sdf/oo/hdfs/data",'

$ echo $s| sed -E ':b;s~[^,:]+.{,3}/rid/(.+)~\1~;Te;h;s~(\w+)/.*~\1~p;g;tb;:e d'
0
27.04.2020, 08:21
3 ответа

Мне нравится использовать mmv для такого рода вещей. Это позволяет вам использовать подстановочные знаки? и *при перемещении файлов. Он обрабатывает каждый подстановочный знак как группу захвата регулярных выражений, вот как я об этом думаю, но он использует #вместо \ для доступа к группам в синтаксисе замены.

Вот демонстрация этой задачи:

$ ls *Folder/*folder2/*
AFolder/Afolder2/123-01-filename.mp4  CFolder/Cfolder2/881-01-filename.mp4 BFolder/Bfolder2/512-01-filname.mp4
$ mmv "*Folder/*folder2/???-*" "#1Folder/#2folder2/#6"
$ ls *Folder/*folder2/*
AFolder/Afolder2/01-filename.mp4  CFolder/Cfolder2/01-filename.mp4 BFolder/Bfolder2/01-filname.mp4

Хитрость заключается в том, что первая строка в основном всегда должна быть в кавычках, чтобы избежать вызова подстановочных знаков из самой оболочки. Во-вторых, помните каждый ? является собственной группой, благодаря чему мы получаем #6 для оставшейся части имени файла.

0
19.03.2021, 02:25

Вы можете найти и вызвать оболочку с помощью-exec

find. -type f -exec sh -c '
  for f; do
    d=${f##*/} d=${d#*[0-9][0-9][0-9]-}
    echo mv -v "$f" "${f%'/'*}/$d"
  done
' _ {} +
  • Эхо предназначено для того, чтобы сообщить вам, как/что будет выполняться. Удалите его, если считаете, что ouptu в порядке.

Фактический вывод выглядит следующим образом.

Выход

renamed './AFolder/Afolder2/123-01-filename.mp4' -> './AFolder/Afolder2/01-filename.mp4'
renamed './BFolder/Bfolder2/512-01-filename.mp4' -> './BFolder/Bfolder2/01-filename.mp4'
renamed './CFolder/Cfolder2/881-01-filename.mp4' -> './CFolder/Cfolder2/01-filename.mp4'
0
19.03.2021, 02:25

Следование вашему собственному предложению об использовании цикла оболочки:

for name in./*/*/???-*.mp4; do
    filename=${name##*/}         # remove directory path
    filename=${filename#???-}    # remove initial three characters and dash

    # prepend directory path to target filename and rename
    mv "$name" "${name%/*}/$filename"
done

Это перебирает имена, которые мы хотим изменить. Для каждого пути часть имени файла из пути извлекается в переменную filenameс использованием стандартной подстановки переменных. Из этого значения удаляются первые три символа и тире. Затем исходный файл можно переименовать, используя это новое значение $filename.

Если вам нужно быть более строгим с соответствием имен файлов, следя за тем, чтобы первые три символа были цифрами, замените каждый ?в приведенных выше шаблонах на [0-9]или [[:digit:]].


Использование утилиты Perl rename:

rename -v 's/...-([^\/]*\.mp4)$/$1/'./*/*/???-*.mp4

Это применит замену Perl к каждому заданному имени файла. Замена соответствует имени файла, но захватывает только часть имени, которую мы хотим оставить в конце (строка в самом конце, не содержащая символа /, с предшествующими тремя символами и тире, которые мы хотели бы удалить ). Совпадающая часть пути заменяется захваченной строкой.

1
19.03.2021, 02:25

Теги

Похожие вопросы