Лучший способ найти/заменить в нескольких файлах?
какой лучший способ сделать это? Я не воин командной строки, но я подумал, что возможно использовать grep
и cat
.
Я просто хочу заменить строку, которая встречается в папке и подпапках. какой лучший способ сделать это? Я использую Ubuntu, если это имеет значение.
Ответы
Ответ 1
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'
Первая часть этого - команда find, чтобы найти файлы, которые вы хотите изменить. Возможно, вам придется изменить это соответствующим образом. Команда xargs
берет каждый найденный файл и применяет к нему команду sed
. Команда sed
берет каждый экземпляр из from и заменяет его на to. Это стандартное регулярное выражение, поэтому измените его, как вам нужно.
Если вы используете SVN, будьте осторожны. Ваши .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'
Ответ 2
Как сказал Пол, вы хотите сначала найти файлы, которые хотите редактировать, а затем редактировать их. Альтернативой использованию find является использование GNU grep (по умолчанию для Ubuntu), например:
grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g'
Вы также можете использовать ack-grep (sudo apt-get install 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
Альтернативой использованию sed является использование perl, который может обрабатывать несколько файлов на команду, например,
grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g'
Здесь perl предлагается редактировать на месте, сначала создавая файл .bak.
Вы можете комбинировать любую из левых сторон трубы с правыми сторонами, в зависимости от ваших предпочтений.
Ответ 3
Я приведу еще один пример для людей, использующих ag
, 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'
Ответ 4
Альтернативой sed
является использование rpl
(например, из http://rpl.sourceforge.net/ или вашего дистрибутива GNU/Linux), например rpl --recursive --verbose --whole-words 'F' 'A' grades/
Ответ 5
comment() {
}
doc() {
}
function agr {
doc 'usage: from=sth to=another agr [ag-args]'
comment -l --files-with-matches
ag -0 -l "$from" "${@}" | pre-files "$from" "$to"
}
pre-files() {
doc 'stdin should be null-separated list of files that need replacement; $1 the string to replace, $2 the replacement.'
comment '-i backs up original input files with the supplied extension (leave empty for no backup; needed for in-place replacement.)(do not put whitespace between -i and its arg.)'
comment '-r, --no-run-if-empty
If the standard input does not contain any nonblanks,
do not run the command. Normally, the command is run
once even if there is no input. This option is a GNU
extension.'
AGR_FROM="$1" AGR_TO="$2" xargs -r0 perl -pi.pbak -e 's/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'
}
Вы можете использовать это так:
from=str1 to=sth agr path1 path2 ...
Не указывайте пути, чтобы использовать текущий каталог.
Обратите внимание, что ag, xargs и perl должны быть установлены и в PATH.