используя поиск и переименование по назначению - PullRequest
1 голос
/ 09 февраля 2012

Теперь, перед тем как встать лицом к лицу и щелкнуть по дублирующейся записи или тому подобное, читайте дальше, этот вопрос является одновременно и теоретическим, и практическим.

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

Позвольте мне установить сцену: допустим, у меня есть 100 файлов, названных так: Image_200x200_nnn_AlphaChars.jpg, где nnn - это инкрементное число, а AlphaChars то есть:

Image_200x200_001_BlueHat.jpg
Image_200x200_002_RedHat.jpg
...
Image_200x200_100_MyCat.jpg

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

find . -type f -name "*.jpg"

Войти на сцену переименовать .Само по себе переименование предполагает, что вы сделаете следующее:

rename <search> <replace> <haystack>

Когда я попытаюсь объединить их с -print0 и xargs и некоторыми регулярными выражениями Iзастрять, и я почти уверен, что это потому, что переименование ищет стог сена или часть поиска ... ( Пожалуйста, объясните, если вы понимаете, что происходит после трубы )

find . -type f -name "*.jpg" -print0 | xargs -0 rename "s/Image_200x200_(\d{3})/img/"

Таким образом, цель состоит в том, чтобы найти, чтобы дать переименовать исходное имя изображения и заменить все до последнего подчеркивания на img

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

Мне нужно понять фундаментальные основы, прежде чем перейти к хардкорным вещам.Кто-нибудь хочет помочь?

Ответы [ 3 ]

3 голосов
/ 09 февраля 2012

Другой подход заключается в том, чтобы избегать использования rename - bash достаточно способен:

find ... -print0 | while read -r -d '' filename; do
  mv "$filename" "img_${filename##*_}"
done

часть ##*_ удаляет все начальные символы до и включая последнее подчеркивание из значения.

1 голос
/ 09 февраля 2012

Если вам не нужно -print0 (т.е. вы уверены, что ваши имена файлов не содержат символов новой строки), вы можете просто сделать:

find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'

Что работает для меня:

~/tmp$ touch Image_200x200_001_BlueHat.jpg
~/tmp$ touch Image_200x200_002_RedHat.jpg
~/tmp$ touch Image_200x200_100_MyCat.jpg
~/tmp$ find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'
~/tmp$ ls
img_BlueHat.jpg  img_MyCat.jpg  img_RedHat.jpg

Что происходит после конвейера, так это то, что xargs анализирует выходные данные find и передает их в разумных порциях команде переименования, которая выполняет регулярное выражение для имени файла и переименовывает файл в результат.

update : Сначала я не пробовал вашу версию с нулевыми терминаторами, но она также работает для меня. Возможно, вы тестировали с другим регулярным выражением?

0 голосов
/ 09 февраля 2012

Что происходит после трубы:

find ... -print0 | xargs -0 rename "s/Image_200x200_(\d{3})/img/"

xargs читает имена файлов, созданные командой find, и выполняет команду rename несколько раз, добавляя несколько имен файлов одновременно. Чистый эффект будет примерно таким:

rename '...' file001 file002 file003 file004 file005 file006 file007 file008 file009 file010
rename '...' file011 file012 file013 file014 file015 file016 file017 file018 file019 file010
rename '...' file021 file022 file023 file024 file025 file026 file027 file028 file029 file010
...
rename '...' file091 file092 file093 file094 file095 file096 file097 file098 file099 file100

find -print0 | xargs -0 - это удобная комбинация для более безопасной обработки файлов, которые могут содержать пробелы.

...