2014-07-07 1 views
1

Я пытаюсь переименовать некоторые каталоги с помощью find и sed, но переключая имя каталога на основе.Переименование каталогов с помощью заметок find и sed

пример имя каталога:

rabbit_stand_a_e 
rabbit_stand_a_ne 

Я хочу, чтобы эти изменения в:

rabbit_a_stand_e 
rabbit_a_stand_ne 

поэтому я хотел бы по существу расщепляется _ и переключатель $ 2 и $ 3 вокруг

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

find . -type d -execdir mv {} `echo {} | sed -E 's/rabbit_([a-z]+)_([abc])_/rabbit_\2_\1_/'` \; 

это ошибки с

mv: cannot move ‘rabbit_stand_a_e’ to a subdirectory of itself, ‘rabbit_stand_a_e/rabbit_stand_a_e’ 
+1

и научиться решать проблемы, как это, выбрав 1 репрезентативного имя файла, и вместо того, чтобы использовать 'find', используйте' эхо rabbit_stand_a_e | sed -E /....// '', чтобы узнать, где ваша проблема. В этом случае вы понимаете, что 'mv' требует и источник и целевой параметр. В любом случае ... удачи! – shellter

+0

Хмм, я думал, что даю два: 'mv {} \' echo ..... '{}, являющийся текущим – Rob

+0

My sed отлично работает на своем собственном уровне, как вы предлагаете' echo rabbit_stand_a_w | sed -E 's/rabbit _ ([az] +) _ ([abc]) _/rabbit_ \ 2_ \ 1 _ /' 'поэтому я должен пропустить, используя -exec или mv – Rob

ответ

1

проблема возникает с момента, когда find делает замену для {} аргумента против, когда ваша оболочка запускает подоболочку (часть команды, заключенную в обратных кавычках).

Все подсчеты оцениваются до Данная команда запускается. Это означает, что вы в конечном итоге используете команду echo {} | sed ...'до. {} получает подменю с именем файла, что означает, что вы буквально эхом отзываете строку "{}" и прокладываете ее в sed. Так как ваш sed шаблон не соответствует "{}", он просто возвращает {} без изменений, оставив вас с этим:

find . -type d -execdir mv {} {} 

Теперь, когда find запускает его заменяет оба вхождения {} с данным именем каталога, следовательно, ваше сообщение об ошибке о попытке для перемещения каталога в себя.

Самый простой способ исправить это, вероятно, интерпретировать всю команду с bash -c и передать в аргументе {} Баш:

find . -type d -execdir bash -c 'mv $1 `echo $1 | sed -E "s/rabbit_([a-z]+)_([abc])_/rabbit_\2_\1_/"`' -- {} \; 

Я думаю, что должен быть простой способ сделать это с xargs, но для меня это не сразу очевидно. Если я подумаю об этом позже, я обновлю свой ответ (или если кто-то еще захочет услышать комментарии, которые будут оценены).


Связанные чтения: Subshell arguments in -exec parameter for find(1)

+0

Спасибо за ваш ответ, отлично. Я смог получить поведение, которое мне нужно, с циклом for, а также – Rob

Смежные вопросы