гну сэд:
$ 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'
Мне нравится использовать 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 для оставшейся части имени файла.
Вы можете найти и вызвать оболочку с помощью-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
' _ {} +
Фактический вывод выглядит следующим образом.
Выход
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'
Следование вашему собственному предложению об использовании цикла оболочки:
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 к каждому заданному имени файла. Замена соответствует имени файла, но захватывает только часть имени, которую мы хотим оставить в конце (строка в самом конце, не содержащая символа /
, с предшествующими тремя символами и тире, которые мы хотели бы удалить ). Совпадающая часть пути заменяется захваченной строкой.