2009-02-09 5 views
33

Каков наилучший способ сделать это? Я не командный воин, но я думал, что есть способ использовать grep и cat.Лучший способ найти/заменить в нескольких файлах?

Я просто хочу заменить строку, которая встречается в папке и подпапках. Каков наилучший способ сделать это? Я бегу ubuntu, если это имеет значение.

-d

+0

Просто перейдите по этой ссылке прямо здесь: http://stackoverflow.com/questions/102083/whats-the-best-tool-to-find-and-replace-regular-expressions-over-multiple-files –

ответ

36
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Первая часть, которая является командой поиска, чтобы найти файлы, которые вы хотите изменить. Возможно, вам придется соответствующим образом изменить это. Команда «xargs» принимает каждый найденный поиск и применяет к нему команду «sed». Команда «sed» принимает каждый экземпляр «from» и заменяет его «на». Это стандартное регулярное выражение, поэтому измените его по мере необходимости.

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

find . ! -regex ".*[/]\.svn[/]?.*" -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

или

find . -name .svn -prune -o -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

+0

Кажется, что эта команда не рекурсирует в подкаталоги. есть ли что-то, что я делаю неправильно? – blackrobot

+0

Что заставляет вас думать, что это не рекурсия в каталоги? –

+0

текстовые файлы в подкаталогах не вносят изменений. то, что я хочу, это сделать: изменить вхождения some.ip.address на someebsite.com во всех поддиректорах. – blackrobot

37

Как сказал Павел, вы хотите, чтобы сначала найти файлы, которые вы хотите изменить, а затем редактировать их. Альтернатива использованию находку, чтобы использовать GNU Grep (по умолчанию на Ubuntu), например:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Вы также можете использовать Ack-Grep (Sudo APT-получить установку Ack-Grep или посетить http://petdance.com/ack/), а также, если вы знаете, что хотите только определенного типа файла, и хотите игнорировать вещи в каталогах управления версиями. например, если вы хотите только текстовые файлы,

ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g' 
# `from` here is an arbitrary commonly occurring keyword 

альтернатива использованию СЭД является использование Perl, который может обрабатывать несколько файлов в команде, например,

grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g' 

Здесь Perl сказано редактировать в сначала создайте файл .bak.

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

+0

Вы можете избежать каталогов управления версиями в «find» с помощью команды «-prune». Например, «find. -name RCS -prune -o -type f -print0» –

+0

Правда, хотя для этого требуется меньше возможностей для создания инструмента, такого как ack, для его обработки. –

+0

ack также принимает параметр '--print0', чтобы использовать null в качестве разделителя между именами файлов, поэтому ваша команда ack будет выглядеть так:' ack -l -print0 -text from | xargs -0 -n 1 sed -i -e 's/from/to/g'' –

3

Альтернатива sed использует rpl (например, доступные от http://rpl.sourceforge.net/ или дистрибутива GNU/Linux), как rpl --recursive --verbose --whole-words 'F' 'A' grades/

14

Я брошу в другом, например, для людей, использующих Ag, The Silver Searcher сделать поиск/заменой операции на нескольких файлах ,

Полный пример:

ag -l "search string" | xargs sed -i '' -e 's/from/to/g' 

Если разбить это вниз, то, что мы получаем:

# returns a list of files containing matching string 
ag -l "search string" 

Далее мы имеем:

# consume the list of piped files and prepare to run foregoing command 
# for each file delimited by newline 
xargs 

Наконец, команда замены строки :

# -i '' means edit files in place and the '' means do not create a backup 
# -e 's/from/to/g' specifies the command to run, in this case, 
# global, search and replace 

sed -i '' -e 's/from/to/g'