2

У меня есть несколько файлов (около 1000), названных так:

abcdefg123456.xyz
abcdefg123457.xyz
abcdefg123458.xyz
abcdefg123459.xyz

Некоторые из файлов имеют 4 дополнительных случайных числа и буквы (в любом порядке) после имени. Возможно, это дубликаты, но не всегда, поэтому мне нужно изменить их на исходный формат, чтобы проверить, являются ли они дубликатами или нет. У них есть этот формат:

abcdefg123456a789.xyz
abcdefg123457b987.xyz
abcdefg123458c879.xyz
abcdefg123459d897.xyz

Иногда есть неправильное расширение,

abcdefg123456.xyzedf
abcdefg123456.xyzfed

Я хочу переименовать эти файлы в исходный формат abcdefg, за которым следуют исходные 6 чисел, то есть удалить последние 4 случайных числа и буквы и удалить конечное расширение назад .xyz. То, что у меня есть, так это:

rename -n "s/[a-z][0-9]{6}.xyz/.xyz/g"  *

Но это не похоже на работу. По какой-то причине вывод:

abcdef.xyz (no numbers)

РЕДАКТИРОВАТЬ: Я был немного разрывается между тем, какой ответ выбрать, потому что оба помогли найти решение. Я пошел на трюки, потому что он помог со второй частью вопроса. Но ваша помощь очень ценится и Марком Перриманом - и, конечно, комментаторами.

2 ответа2

2

Решение

Чтобы удалить 4 цифры / буквы, предшествующие полной остановке для всех файлов, вы можете использовать следующий цикл:

for file in *.xyz ; do
    NEWFILE=$(echo "$file" |sed -re 's/[a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9](\.)/\./g')
    mv -v $file $NEWFILE
done

объяснение

for file in *.xyz ; do

Перебирает каждый файл с расширением .xyz

NEWFILE=$(echo "$file" |sed -re 's/[a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9](\.)/\./g')

Создайте переменную с именем NEWFILE содержащую имя файла после удаления шаблона, который соответствует [a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9] (смесь 4 цифры или буквы) и сопровождается полной остановкой ((\.)).

mv -v $file $NEWFILE

Переместите файл с новым именем, -v распечатает процесс перемещения в следующем формате

`abcdefg123456a789.xyz` -> `abcdefg123456.xyz`

В настоящее время это не распространяется на исправление расширений, но можно использовать решение, подобное приведенному выше, но с командой sed, являющейся sed 's/\.xyz.*/\.xyz/g' .

1

Пытаться

rename -n -f 's/([a-z]*[0-9]{6})[a-z0-9]{0,4}(\.xyz).*/$1$2/g'  *

Это работает с версией rename выпущенной с помощью Debian и Ubuntu (см. Справочную страницу по адресу http://www.computerhope.com/unix/rename.htm).

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

Почему это работает

  • ([a-z]*[0-9]{6}) - это захваченный abcdefg123456, который можно заменить на $1 при замене.
  • (\.xyz) - расширение, захваченное и называемое $2 при замене.
  • Все остальное [a-z0-9]{0,4} (до 4 букв / цифр) и .* ( Что угодно после расширения) сопоставляется, а затем игнорируется при замене.

Бонус Чтобы удалить все файлы, которые все еще не соответствуют вашему шаблону (например, если вы не использовали опцию force выше), используйте find чтобы вывести их и удалить. (Запустите без -exec rm {} для пробного запуска.)

find . -regextype posix-egrep -regex '.*/[a-z]*[0-9]{6}[a-z0-9]{4}\.xyz.*|[a-z]*[0-9]{6}\.xyz.*' -exec rm {}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .