Можно сделать что-то сырое с маленьким сценарием Perl, который проинструктирован для выполнения замен линию за линией (-l -pe
) на месте на файлах передал как аргументы (-i
):
perl -i -l -pe '
if (/from/) { # is the source text present on this line?
printf STDERR ("%s: %s [y/N]? ", $ARGV, $_); # display a prompt
$r=; # read user response
if ($r =~ /^[Yy]/) { # if user entered Y:
s/from/to/g; # replace all occurences on this line
}' /path/to/files
Возможные улучшения должны были бы окрасить части подсказки и вещей поддержки как “замена всеми происшествиями в текущем файле”. Отдельно запрос каждого возникновения на строке был бы более трудным.
Вторая часть, соответствуя файлам. если нет слишком многих включенных файлов, и Вы выполняете zsh, можно соответствовать всем файлам в текущем каталоге и его подкаталогах рекурсивно:
perl -i -l -pe '…' **/*(.)
Если Ваша оболочка является ударом ≥4, можно работать perl … **/*
, но это произведет побочные сообщения об ошибках, потому что sed попытается (и сбой) работать на каталогах. Если Вы только хотите выполнить замену в ряде файлов, таких как файлы C, можно ограничить соответствия (который работает или в ударе ≥4 или в zsh):
perl -i -l -pe '…' **/*.[hc]
При необходимости в более прекрасном управлении, по которому файлам Вы заменяете, или Ваша оболочка не имеет рекурсивного каталога, соответствующего конструкции **
, или если Вы имеете слишком много файлов и получаете “командную строку слишком долго” ошибка, использовать find
. Например, для выполнения замены во всех названных файлах *.h
или *.c
в текущем каталоге и его подкаталогах (в более старых системах, Вы, возможно, должны использовать \;
вместо +
в конце строки ( +
форма быстрее, но не доступна везде).
find . -type f -name '*.[hc]' -exec perl -i -l -pe '…' {} +
Однако я придерживался бы интерактивного редактора, если Вам нужно взаимодействие. Gert показал путь к этому в Vim, хотя он требует открытия всех файлов, которые Вы хотите перерыть, который может быть проблемой, если существует много.
В Emacs вот то, как можно сделать это:
M-x find-name-dired
(укажите каталог верхнего уровня), или M-x find-dired
(укажите произвольное find
командная строка).t
отметить все файлы, затем Q
(dired-do-query-replace-regexp
) выполнить замену с запросом на отмеченных файлах.