2013-03-08 7 views
52

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

find . -name '*-GHBAG-*' -exec bash -c 'echo mv $0 ${0/GHBAG/stream-agg}' {} \; 

Как я запускаю эту команду, я вижу некоторые выходы, как этот

mv ./report-GHBAG-1B ./report-stream-agg-1B 
mv ./reoprt-GHBAG-0.5B ./report-stream-agg-0.5B 

Однако в конце, когда я запустил ls, я вижу старые имена файлов.

+0

Stack Overflow это сайт для программирования и разработки вопросов. Этот вопрос кажется вне темы, потому что речь идет не о программировании или разработке. См. [Какие темы можно задать здесь] (http://stackoverflow.com/help/on-topic) в Справочном центре. Возможно, лучше сказать [Суперпользователь] (http://superuser.com/) или [Unix & Linux Stack Exchange] (http://unix.stackexchange.com/). Также см. [Где я пишу вопросы о Dev Ops?] (Http://meta.stackexchange.com/q/134306) – jww

+0

Лучший вопрос для большинства людей, у которых google это https://stackoverflow.com/questions/1086502/rename-multiple-files-in-unix – tripleee

ответ

76

Вы эхо-команду «mv», а не выполняете ее. Изменить на:

find . -name '*-GHBAG-*' -exec bash -c 'mv $0 ${0/GHBAG/stream-agg}' {} \; 
+10

Спасибо за это решение. Но лучше окружать эти переменные в '' ', если у вас есть' 'на имена файлов.' Mv '$ 0 "" $ {0/GHBAG/stream-agg} "'. – erickb

+1

@erickb great catch =) – Kyle

+3

Я понятия не имел вы могли бы выполнять замены на переменные в bash следующим образом: Fantastic! – Snorfalorpagus

34

Я предложил бы использовать команду rename для выполнения этой задачи. rename переименовывает имена файлов, предоставляемые в соответствии с правилом, заданным как регулярное выражение Perl.

В этом случае, вы можете использовать:

rename 's/GHBAG/stream-agg/' *-GHBAG-* 
+0

Спасибо. Это намного проще, но я играл с 'exec' – mahmood

+0

Конечно,' find' с '-exec' имеет то, что он рекурсивно ищет каталог, который rename не может, но 'переименовать' будет быстрее, так как это не вызовет процесс для каждого переименованного файла. – anumi

+1

@anumi' man find' показывает '-exec command {} +' как вариант для выполнения только одного экземпляра на всех найденные файлы Хотя, я не знаю, полезно ли это с примером в исходном вопросе –

17

В ответ на комментарий anumi, вы могли бы в поисках эффекта рекурсивного вниз каталогов путем сопоставления «**»:

rename 's/GHBAG/stream-agg/' **/*-GHBAG-* 
+1

Я пробовал это, и он работал только для одного пути из нескольких подкаталогов. 'найти. -name "*: *" 'все еще выдал список файлов после запуска' rename -v '/:/- /' **/*: * ', а второй переименовал-дал« _No такой файл или каталог_ »уведомлять , (Debian 6) –

+1

rename не является универсальной командой unix. –

1

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

# bashrc 
function file_replace() { 
    for file in $(find . -type f -name "$1*"); do 
    mv $file $(echo "$file" | sed "s/$1/$2/"); 
    done 
} 

Я обычно будет работать с find . -type f -name "MYSTRING*" заранее, чтобы проверить матчи перед заменой.

Например:

file_replace "Slider.js" "RangeSlider.ts" 

renamed: packages/react-ui-core/src/Form/Slider.js -> packages/react-ui-core/src/Form/RangeSlider.ts 
renamed: stories/examples/Slider.js -> stories/examples/RangeSlider.ts 

или канаву типов файлов, чтобы сделать его еще более жадными

file_replace Slider RangeSlider 

renamed: packages/react-ui-core/src/Form/Slider.js -> packages/react-ui-core/src/Form/RangeSlider.js 
renamed: stories/examples/Slider.js -> stories/examples/RangeSlider.js 
renamed: stories/theme/Slider.css -> stories/theme/RangeSlider.css 
Смежные вопросы