LINUX.ORG.RU

Авто переименовывание файлов find awk mv


0

1

Доброго времени суток! Подскажите пожалуйста, как средствами «find | awk | mv» можно переименовать файлы по заданной маске ? У меня есть команда

 find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' -mmin +60 -exec basename {} \; | awk -F_ -v OFS="_" '{sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);print $3,$1,$2,$4}' 
которая меняет название файла и выводит на экран с «now_720p_2014-05-19-18.12.01.784-FET_0.mp4» на «2014-05-19_18-12-01_now_720p_0.mp4». Однако, вывод на экран меня не устраивает. Подскажите пожалуйста, как можно добавить mv для полноценного переименовывания файла на диске? Заранее спасибо за помощь.



Последнее исправление: NZT (всего исправлений: 1)

Ответ на: комментарий от anonymous

К сожалению, у меня нет таких глубоких познаний, как у Вас. Можете ли Вы поподробнее рассказать о том, как через find & awk использовать mv ?

NZT
() автор топика

Код нужно оборачивать в [code]

sin_a ★★★★★
()
Ответ на: комментарий от proud_anon

Выводятся следующие строки:

 [oleg@media ~]# find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' -mmin +60 -exec basename {} \; | awk -F_ -v OFS="_" '{sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);print $3,$1,$2,$4}'
2014-05-19_18-12-46_now_720p_0.mp4
2014-05-19_18-12-05_now_aac_0.mp4
2014-05-19_18-12-50_now_aac_0.mp4
2014-05-19_18-12-01_now_720p_0.mp4
2014-05-19_18-12-49_now_360p_0.mp4
2014-05-19_18-12-05_now_360p_0.mp4 

если изменить

print $3,$1,$2,$4
на
cmd = sprintf("echo %s_%s_%s_%s", $3, $1, $2, $4"); system(cmd)

то выводится следующее:

[oleg@media ~]# find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' -mmin +60 -exec basename {} \; | awk -F_ -v OFS="_" '{sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("echo %s_%s_%s_%s", $3, $1, $2, $4"); system(cmd)}'
awk: {sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("echo %s_%s_%s_%s", $3, $1, $2, $4"); system(cmd)}
awk:                                                                                                                               ^ unterminated string
find: `basename' прерван по сигналу 13
find: `basename' прерван по сигналу 13
find: `basename' прерван по сигналу 13
find: `basename' прерван по сигналу 13
find: `basename' прерван по сигналу 13
find: `basename' прерван по сигналу 13

NZT
() автор топика

Надеюсь смысл понятен?

$ rename -n 's/(now_720p)_(\d+-\d+-\d+-\d+\.\d+\.\d+)\..*_(\d*).mp4/$2_$1_$3.mp4/' now_720p_2014-05-19-18.12.01.784-FET_0.mp4

now_720p_2014-05-19-18.12.01.784-FET_0.mp4 renamed as 2014-05-19-18.12.01_now_720p_0.mp4

sdio ★★★★★
()
Последнее исправление: sdio (всего исправлений: 1)
Ответ на: комментарий от NZT

Тогда что будет, если заменить:

awk -F_ -v OFS="_" '{sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);print $3,$1,$2,$4}'
На
awk -F_ -v OFS="_" '{orig = $0; sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("echo mv %s %s_%s_%s_%s", orig, $3, $1, $2, $4); system(cmd)}'

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon
[oleg@media ~]# find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' -mmin +60 -exec basename {} \; | awk -F_ -v OFS="_" '{orig = $0; sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("echo mv %s %s_%s_%s_%s", orig, $3, $1, $2, $4); system(cmd)}'
mv now_720p_2014-05-19-18.12.46.266-FET_0.mp4 2014-05-19_18-12-46_now_720p_0.mp4
mv now_aac_2014-05-19-18.12.05.572-FET_0.mp4 2014-05-19_18-12-05_now_aac_0.mp4
mv now_aac_2014-05-19-18.12.50.015-FET_0.mp4 2014-05-19_18-12-50_now_aac_0.mp4
mv now_720p_2014-05-19-18.12.01.784-FET_0.mp4 2014-05-19_18-12-01_now_720p_0.mp4
mv now_360p_2014-05-19-18.12.49.996-FET_0.mp4 2014-05-19_18-12-49_now_360p_0.mp4
mv now_360p_2014-05-19-18.12.05.567-FET_0.mp4 2014-05-19_18-12-05_now_360p_0.mp4

А как выполнить полученный результат одновременно вместе с командой? пробовал убрать echo, но возникла ошибка:

[oleg@media ~]# find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' -mmin +60 -exec basename {} \; | awk -F_ -v OFS="_" '{orig = $0; sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("mv %s %s_%s_%s_%s", orig, $3, $1, $2, $4); system(cmd)}'
mv: невозможно выполнить stat для «now_720p_2014-05-19-18.12.46.266-FET_0.mp4»: Нет такого файла или каталога
mv: невозможно выполнить stat для «now_aac_2014-05-19-18.12.05.572-FET_0.mp4»: Нет такого файла или каталога
mv: невозможно выполнить stat для «now_aac_2014-05-19-18.12.50.015-FET_0.mp4»: Нет такого файла или каталога
mv: невозможно выполнить stat для «now_720p_2014-05-19-18.12.01.784-FET_0.mp4»: Нет такого файла или каталога
mv: невозможно выполнить stat для «now_360p_2014-05-19-18.12.49.996-FET_0.mp4»: Нет такого файла или каталога
mv: невозможно выполнить stat для «now_360p_2014-05-19-18.12.05.567-FET_0.mp4»: Нет такого файла или каталога
NZT
() автор топика
Ответ на: комментарий от sdio

для тех кто в танке, можете поподробней расписать строку

's/(now_720p)_(\d+-\d+-\d+-\d+\.\d+\.\d+)\..*_(\d*).mp4/$2_$1_$3.mp4/'

NZT
() автор топика
Ответ на: комментарий от NZT

А как выполнить полученный результат одновременно вместе с командой? пробовал убрать echo, но возникла ошибка:

Это потому, что find вызывает basename и, таким образом, awk работает с именами файлов, а не с путями.

Надо так:

awk -F_ -v OFS="_" '{orig = $0; sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);cmd = sprintf("mv /opt/media/rec/%s /opt/media/rec/%s_%s_%s_%s", orig, $3, $1, $2, $4); system(cmd)}'

Или так же сделать, как ты сделал (просто убрать echo), но сначала зайти в /opt/media/rec:

cd /opt/media/rec

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 3)
Ответ на: комментарий от NZT

Я не могу вам за 5 минут прочесть курс «регулярные выражения»

Скобками выделяем части исходного имени, каждой паре скобок соответствует $1, $2, $3, ... в правой части. \d — одна цифра

sdio ★★★★★
()
Ответ на: комментарий от proud_anon

спасибо! заработало! basename используется из-за того, что awk неправильно переименовываем файлы (нужно править regex, а я до этого еще не дошел). Результат

[root@media ~]# find /opt/media/rec -maxdepth 1 -type f -name '*.mp4' | awk -F_ -v OFS="_" '{sub(/\.[^.]*$/,"",$3);$3=gensub(/-([^-]*$)/,"_\\1","g",$3);gsub(/\./,"-",$3);print $3,$1,$2,$4}'
2014-05-20_14-52-50_/opt/media/rec/now_360p_0.mp4
2014-05-20_14-52-50_/opt/media/rec/now_aac_0.mp4

Если подскажите как избавиться от basename, буду очень признателен.

NZT
() автор топика
Ответ на: комментарий от NZT

Если подскажите как избавиться от basename, буду очень признателен.

Если надо только один раз всё переименовать в /opt/media/rec, то не надо избавляться от basename, надо то сделать, что я выше написал. Если это надо делать часто, то тут нужно, наверное, «систему менять», возможно, перейти на rename, как sdio советует.

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

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

NZT
() автор топика
Ответ на: комментарий от sdio

Как эту команду

rename -n 's/(now_720p)_(\d+-\d+-\d+-\d+\.\d+\.\d+)\..*_(\d*).mp4/$2_$1_$3.mp4/' now_720p_2014-05-19-18.12.01.784-FET_0.mp4p
можно преобразовать чтобы менять все имена файлов в каталоге /dir1/dir2, с учетом того, что последний раз файл модифицировался более 3 часов назад ? (-mtime +180)

NZT
() автор топика
Ответ на: комментарий от sdio

помимо переименовывания, необходимо из имени файла, например, «now_360p_2014-05-20-15.26.15.898-FET_0.mp4» преобрезовать чч.мм.сс.мсс на чч-мм-сс, удалить микросекунды и убрать слово FET

NZT
() автор топика
Ответ на: комментарий от NZT

now_720p_2014-05-19-18.12.01.784-FET_0.mp4 renamed as 2014-05-19-18.12.01_now_720p_0.mp4

А в приведенном мной примере остался FET и миллисекунды?

sdio ★★★★★
()
Ответ на: комментарий от sdio

Да:

$ rename -n 's/(now_720p)_(\d+-\d+-\d+-\d+\.\d+\.\d+)\..*_(\d*).mp4/$2_$1_$3.mp4/' now_720p_2014-05-19-18.12.01.784-FET_0.mp4

now_720p_2014-05-19-18.12.01.784-FET_0.mp4 renamed as 2014-05-19-18.12.01_now_720p_0.mp4 

Без awk наверно никак.

NZT
() автор топика
Ответ на: комментарий от NZT

Что "да" ?

Это now_720p_2014-05-19-18.12.01.784-FET_0.mp4 будет переименовано в это 2014-05-19-18.12.01_now_720p_0.mp4

где в этом 2014-05-19-18.12.01_now_720p_0.mp4 FET и миллисекунды?

sdio ★★★★★
()
Ответ на: комментарий от sdio

остановлюсь на первом варианте, мне еще учить и учить. Всем спасибо за помощь.

NZT
() автор топика
Ответ на: комментарий от NZT

Нет, не знаю. если подскажите несколько грамотных ссылок, буду рад.

Тогда можно начать здесь: http://www.regular-expressions.info/
Несмотря на обилие рекламы (собственных продуктов автора), сайт толковый.
Читай либо Quickstart, либо Tutorial.
А практиковаться можно, взяв какой-нибудь текстовый редактор (например, Kate) и там выполняя поиск по регулярному выражению.

proud_anon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.