unix найти и заменить текст в dir и subdirs - PullRequest
1 голос
/ 18 января 2012

Я пытаюсь изменить имя «my-silly-home-page-name.html» на «index.html» во всех документах в указанном главном каталоге и подкаталогах.

Я видел это: Сценарий оболочки - поиск и замена текста в нескольких файлах с использованием списка строк .

И это: Как изменить все вхождения слова во всех файлах в каталоге

Я пробовал это:

grep -r "my-silly-home-page-name.html" .

Этонаходит строки, на которых существует текст, но теперь я хотел бы заменить «my-silly-home-page-name» на «index».Как бы я сделал это с помощью sed или perl?Или мне даже нужен sed / perl?

Что-то вроде:

grep -r "my-silly-home-page-name.html" . | sed 's/$1/'index'/g'

?

Также;Я пытаюсь это с помощью Perl, и я пытаюсь сделать следующее:

perl -i -p -e 's/my-silly-home-page-name\.html/index\.html/g' *

Это работает, но я получаю сообщение об ошибке, когда Perl встречает каталоги, говоря: «Не удается выполнить редактирование на месте: SOMEDIR-NAMEобычный файл, <> строка N "

Спасибо, jml

Ответы [ 3 ]

7 голосов
/ 18 января 2012
find . -type f -exec \
   perl -i -pe's/my-silly-home-page-name(?=\.html)/index/g' {} +

Или, если ваш find не поддерживает -exec +,

find . -type f -print0 | xargs -0 \
   perl -i -pe's/my-silly-home-page-name(?=\.html)/index/g'

Оба они передают Perl в качестве аргументов как можно больше имен одновременно. Оба работают с любым именем файла, включая те, которые содержат переводы строк.


Если вы работаете в Windows и используете сборку Perl для Windows (в отличие от сборки Cygwin), -i не будет работать, если вы не создадите резервную копию оригинала. Измените -i на -i.bak. Затем вы можете пойти и удалить резервные копии, используя

find . -type f -name '*.bak' -delete
1 голос
/ 18 января 2012

Это должно сделать работу:

find . -type f -print0 | xargs -0 sed -e 's/my-silly-home-page-name\.html/index\.html/g' -i

В основном он рекурсивно собирает все файлы из данного каталога (. в примере) с find и запускает sed с той же подстановкойкоманда, как в команде perl в вопросе через xargs.

Что касается вопроса о sed против perl, я бы сказал, что вам следует использовать тот, который вам удобнеес, так как я не ожидаю огромных различий (команда замещения одна и та же).

0 голосов
/ 18 января 2012

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

find . -name oldname.html |perl -e 'map { s/[\r\n]//g; $old = $_; s/oldname.txt$/newname.html/; rename  $old,$_  } <>';

Fyi, grep ищет шаблон; find ищет файлы.

...