Ви можете зробити щось неочищене за допомогою невеликого сценарію 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=<STDIN>; # 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 '…' **/*(.)
Якщо ваша оболонка є bash ≥4, ви можете запустити perl … **/*, але це призведе до помилкових повідомлень про помилки, оскільки sed буде намагатися (і не працювати) для запуску в каталогах. Якщо ви хочете виконати заміну лише в наборі файлів, таких як файли C, ви можете обмежити відповідність (що працює в bash ≥4 або zsh):
perl -i -l -pe '…' **/*.[hc]
Якщо вам потрібен тонший контроль над тим, які файли ви замінюєте, або у вашій оболонці немає конструкції відповідного рекурсивного каталогу **, або якщо у вас занадто багато файлів, і помилка "командний рядок занадто довга", використовуйте find. Наприклад, для заміни у всіх файлах, названих *.hабо *.cу поточному каталозі та його підкаталогах (у старих системах вам може знадобитися використовувати \;замість +кінця рядка ( +форма швидша, але доступна не скрізь).
find . -type f -name '*.[hc]' -exec perl -i -l -pe '…' {} +
Попри це, я б дотримувався інтерактивного редактора, якщо вам потрібна взаємодія. Герт показав шлях до цього у Vim , хоча вимагає відкриття всіх файлів, які ви хочете шукати, що може бути проблемою, якщо їх багато.
У Emacs, ось як це зробити:
- Зберіть імена файлів за допомогою
M-x find-name-dired(вкажіть каталог верхнього рівня) або M-x find-dired(вкажіть довільний findкомандний рядок).
- У отриманому розділеному буфері натисніть,
tщоб позначити всі файли, а потім Q( dired-do-query-replace-regexp), щоб здійснити заміну із запитом на позначені файли.
s/from/to/gіз проблемою форматування після неї, а неs/from/to/gcз акцентом на те,cяк ви намагалися записати (ви не можете цього зробити з Markdown, ви могли б це зробити з<code>та<strong>теги HTML).