Переименование нескольких файлов с помощью sed

Переименование нескольких файлов с помощью sed

У меня есть следующий набор файлов

top_axi_256_wrapper_05.02.01.14.00_sample06.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz

Я хочу заменить 05.02.01.14.00часть на 05_02_01_14_00. Так что конечный результат — это следующие переименованные файлы

top_axi_256_wrapper_05_02_01_14_00_sample06.tgz
top_axi_128_wrapper_05_02_01_14_00_sample06.tgz

Мой каталог также может содержать следующие типы имен файлов.

a72_a_0.0.0_0.00.04_ac_dc.tgz

Здесь я хочу переименовать файл в

a53_1c_256K_a_0_0_0_0_00_04_ac_dc.tgz

Как это сделать?

решение1

По сути, вам нужно заменить точку на подчеркивание, за исключением последней.

Для этого можно использовать расширение параметров bash:

for file in * ; do
    replace_all=${file//./_}
    newname=${replace_all%_*}.${replace_all##*_}
    mv "$file" "$newname"
done
  • //./_означаетзаменить все точки на подчеркивания
  • %_*означаетудалить все после последнего подчеркивания
  • ##*_означаетудалить все до последнего подчеркивания

Или вы можете сначала сохранить расширение, затем удалить его, заменить все точки на подчеркивания и добавить расширение обратно. Оставлено в качестве упражнения для читателя.

решение2

Утилита perlна основе - renameможет использовать любые perlоператоры для переименования файлов, а не только s///оператор поиска и замены или y//оператор перевода (просто убедитесь, что вы указали $_то, во что хотите переименовать файл).

От man rename:

"rename" переименовывает предоставленные имена файлов в соответствии с правилом, указанным в качестве первого аргумента. Аргумент perlexpr — это выражение Perl, которое, как ожидается, изменит $_строку в Perl по крайней мере для некоторых из указанных имен файлов. Если заданное имя файла не изменено выражением, оно не будет переименовано. Если в командной строке не указаны имена файлов, имена файлов будут считываться через стандартный ввод.

Например:

rename 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' files

Это разделяет имена файлов на базовое имя ($b) и расширение ($e). Затем в $b все точки ( .) заменяются подчеркиваниями. Наконец, $_устанавливается значение "$b.$e".

Вывод (с -vопцией verbose):

$ touch top_axi_256_wrapper_05.02.01.14.00_sample06.tgz \
    top_axi_128_wrapper_05.02.01.14.00_sample06.tgz \
    a72_a_0.0.0_0.00.04_ac_dc.tgz

$ rename -v 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' *
a72_a_0.0.0_0.00.04_ac_dc.tgz renamed as a72_a_0_0_0_0_00_04_ac_dc.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_128_wrapper_05_02_01_14_00_sample06.tgz
top_axi_256_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_256_wrapper_05_02_01_14_00_sample06.tgz

Кстати, используйте -nпри проверке своих renameутверждений. Еще от man rename:

-н, -ноно

Никаких действий: вывести имена файлов, которые необходимо переименовать, но не переименовывать их.

perl renameдоступен в виде пакетов для большинства дистрибутивов (например, renameпакет в Debian) или изhttps://metacpan.org/release/File-Rename

Связанный контент