Как пакетно переименовывать файлы с помощью сценария bash?

У меня есть несколько файлов в одном каталоге с указанным ниже форматом, поэтому я хочу переименовать все, как показано ниже:

От

27_07_2017file1vc001vpxd-1605.log
27_07_2017case2vc001vpxd-9169.log
27_07_2017server3vc001vpxd-4640.log
27_07_2017file24vc001vpxd-9170.log
27_07_2017files5vc001vpxd-4641.log

до

file1vc001vpxd-1605_27_07_2017_1.log
case2vc001vpxd-9169_27_07_2017_1.log
server3vc001vpxd-4640_27_07_2017_1.log
file24vc001vpxd-9170_27_07_2017_1.log
files5vc001vp-4641_27_07_2017_1.log

Необходимо изменить формат файлов с datefilename.log для форматирования filename.date_1.log

Пожалуйста, не предлагайте использовать команду rename , поскольку она не работает на моем сервере Linux.

Спасибо

0
01.08.2017, 11:13
2 ответа

Я не знаю всех возможных вариантов имен файлов, поэтому я покажу вам общий подход, который вы можете адаптировать к своим потребностям.

Вы можете перебирать файлы с помощью цикла forили использовать find -execпо своему усмотрению. Я думаю, вы в основном хотите знать, как разрезать имя файла на части и по-разному их соединять.

Вы можете передать имя в инструмент, например sed, и создать регулярное выражение для определения нужных частей:

newname=`echo "$oldname"|sed -E 's/([0-9-]{10})(.*).log/\2_\1_1.log/'`

Если вы поместите ()вокруг этих частей, вы можете ссылаться на них как \1, \2и т. д. в строке замены. Если вам нужно адаптировать его, прочитайте страницу manиз sedили спросите здесь, если у вас не получится.

Другой возможностью является использование расширения переменных POSIX:

Вы, наверное, знаете, что

${oldname#*201?}

удалит префикс даты вашего имени файла (?может соответствовать любому символу, поэтому это работает для 2010–2019 годов, если этого достаточно. В противном случае адаптируйтесь.)

Их также можно комбинировать:

${oldname%${oldname#*201?}}

Будет удалена часть, которую мы извлекли выше, так что вы получите только дату. Таким образом, вы можете разделить части имени файла и вставить их в другом порядке.

0
28.01.2020, 02:33

Вот сценарий bash для этого (, пересмотренный для общего случая на основе пересмотренного вопроса OP):

for file in *.log; do 
    echo mv "$file" "${file:10:$((${#file}-14))}".${file::10}_1.log;
done

Над ${file:X:Y}находится синтаксис расширения подстроки bash ${variable:offset:length}и получить длину символов, начиная с смещения от егоvariable(или параметра )и переименовать с помощью mv. Просто удалите echo, как только убедитесь, что результат ожидаемый, как вы хотите.

Вышеизложенный результат выглядит следующим образом:

mv 27_07_2017case5.log case5.27_07_2017_1.log
mv 27_07_2017file1vc001vpxd-1605.log file1vc001vpxd-1605.27_07_2017_1.log
mv 27_07_2017file2vc001vpxd-9169.log file2vc001vpxd-9169.27_07_2017_1.log
mv 27_07_2017file3vc001vpxd-4640.log file3vc001vpxd-4640.27_07_2017_1.log
mv 27_07_2017file4vc001vpxd-9170.log file4vc001vpxd-9170.27_07_2017_1.log
mv 27_07_2017file5.log file5.27_07_2017_1.log
mv 27_07_2017file5vc001vpxd-4641.log file5vc001vpxd-4641.27_07_2017_1.log
mv 27_07_2017number-blahblahblah5.log number-blahblahblah5.27_07_2017_1.log
mv 27_07_2017number-blahblahblah5AAABBC.log number-blahblahblah5AAABBC.27_07_2017_1.log
mv 27_07_2017number5.log number5.27_07_2017_1.log
2
28.01.2020, 02:33

Теги

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