Итак, я хочу изменить несколько файлов одновременно с помощью одной команды. Вот что у меня есть на данный момент:
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' {} ';'
%
выбрать все строки
s
замена
g
заменить все экземпляры в каждой строке
x
сохранить и закрыть