2012-02-09 4 views
1

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

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

Позвольте мне установить сцену: Допустим, у меня есть 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 и некоторые регулярные выражения я застревают, и я почти уверен, что это потому, что переименовывать ищу стог или в поисковой часть ... (Пожалуйста, объясните, если вы понимаете, что происходит после того, как трубы)

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

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

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

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

+2

Для нечувствительности к регистру do '-iname' вместо' -name'. – AlG

+1

Если вы знаете, что ваши файлы находятся в одной директории, вы можете найти «найти». 'find' идеально подходит, когда ваши целевые файлы разбросаны по иерархии каталогов, но в одном каталоге вы найдете шаблоны glob или extended-glob (http://www.gnu.org/software/bash/manual/ bashref.html # Pattern-Matching). Тогда у вас есть: 'rename 's/Image_200x200 _ (\ d {3})/img /" * .jpg –

+0

Мне нравится упрощать, спасибо @ glenn-jackman, но это переименование поиска, очевидно, будет усложняться, Я использую find, так как следующим шагом было бы сделать именно это, рекурсивно найти и заменить файлы и переименовать их, а потом получить уродливые имена с именами или специальными символами ... но простые базовые важны для начала:) –

ответ

3

Другой подход, чтобы избежать использования rename - Баш способен достаточно:

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

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

+0

Так получилось, что переименование в CentOS и RedHat НЕ является версией perl, объясняя, почему он не отвечает на регулярные выражения, которые я им даю. Кажется, что это find-read-mv является моим единственным решением на данный момент. Спасибо @ glenn-jackman, он работает. Теперь, чтобы понять, что все это значит, т.е. вернуться к книгам ... –

1

Если вам не нужно -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 и передает его в разумные куски команде rename, которая выполняет регулярное выражение в имени файла и переименовывает файл в результат.

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

+0

Я просто попробовал шаг за шагом на моем ящике, и ничего не происходит. Вот почему я задал вопрос, поскольку я думал, что делаю что-то неправильно. Использование ** Linux CentOS-55-64-минимальный 2.6.18-274.17.1.el5 # 1 SMP GNU/Linux ** с _/usr/bin/rename_ –

+0

Нечетный, я тестирую debian, с 'rename' из пакета 'perl-5.10.1' и' findutils' версии 4.4.2-1 + b1'. 'Linux 2.6.32.33'. – beerbajay

+0

Ну CentOS 5.5 с 'rename'from' util-linux-2.13-0.56.el5.x86_64' и 'find' из' findutils-4.2.27-6.el5.x86_64', другой сервер с использованием RedHat 6 имеет тот же болезни, он использует те же пакеты. Я в тупик ... Тогда я думаю, что понимаю теорию ... Что-то еще не так, я думаю ... но что ... –

0

Что происходит после того, как трубы:

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 удобная комбинация для более безопасного обращения с файлами, которые могут содержать пробелы.