Назад | Перейти на главную страницу

Как рекурсивно искать и заменять из командной строки в системе unix / linux

Итак, я хочу изменить несколько файлов одновременно с помощью одной команды. Вот что у меня есть на данный момент:

find -regex ".*\.ext$" | xargs grep -l searchText 2> /dev/null | xargs -i sed 's/searchText/replaceText/' > {}.new

Что оно делает:

Я нахожу файлы с расширением ext, отправляю их в grep, игнорируя ошибки, а затем отправляю в sed для замены с новым именем файла file.ext.new.

Проблема, похоже, в том, что перенаправление> в sed предотвращает замену {} именем файла.

Любые идеи? или лучшее решение?

Если вы можете жить с обновлением файла на месте и созданием резервной копии.

find -name '*.ext' -exec sed -i'.backup' 's/searchText/replaceText/' {} +

Редактировать:

Если у вас абсолютно не может быть файлов таким образом - измененный файл на месте и исходный с расширением - тогда вы можете добавить дополнительную команду в конце exec, чтобы переместить их.

Обратные кавычки, также известные как. На помощь приходят «внешние команды».

sed -i '.bak' 's/searchText/replaceText/g' `grep -l searchText \`find . -name '*.ext'\``

Здесь мы находим поиск '* .ext', который затем передается в виде файлов для поиска grep, которые передаются sed, который выполняет фактическую замену. Его преимущество в том, что он не запускает новый процесс grep для каждого найденного файла. То же для sed.

Да, Perl отлично подходит для этого, и вот весь скрипт для этого.

Perl отлично подходит для этого:

find . -type f -name '*.ext' | xargs perl -pi.bak -e 's/searchText/replaceText/g'

sed имеет параметр --in-place.

Вы можете использовать Vim в режиме Ex:

find -name '*.ext' -exec ex -sc '%s/OLD/NEW/g|x' {} ';'
  1. % выбрать все строки

  2. s замена

  3. g заменить все экземпляры в каждой строке

  4. x сохранить и закрыть