Możesz zrobić coś prymitywnego za pomocą małego skryptu Perla, który jest instruowany do wykonywania zamiany wiersz po wierszu ( -l -pe
) na plikach przekazywanych jako argumenty ( -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
Możliwe ulepszenia polegałyby na kolorowaniu części monitu i wsparciu takich rzeczy jak „zamień wszystkie wystąpienia w bieżącym pliku”. Oddzielne monitowanie o każde wystąpienie w linii byłoby trudniejsze.
Druga część, dopasowanie plików. jeśli nie ma zbyt wielu plików i korzystasz z zsh, możesz rekurencyjnie dopasować wszystkie pliki w bieżącym katalogu i jego podkatalogach:
perl -i -l -pe '…' **/*(.)
Jeśli twoja powłoka ma bash ≥4, możesz uruchomić perl … **/*
, ale spowoduje to fałszywe komunikaty o błędach, ponieważ sed spróbuje (i nie powiedzie się) uruchomić w katalogach. Jeśli chcesz wykonać zamianę tylko w zestawie plików, takich jak pliki C, możesz ograniczyć dopasowania (działa to zarówno w bash ≥4, jak i zsh):
perl -i -l -pe '…' **/*.[hc]
Jeśli potrzebujesz dokładniejszej kontroli nad zamienianymi plikami lub twoja powłoka nie ma rekurencyjnej struktury dopasowywania katalogu **
lub jeśli masz zbyt wiele plików i pojawia się błąd „zbyt długiej linii poleceń”, użyj find
. Na przykład, aby wykonać zamianę we wszystkich nazwanych plikach *.h
lub *.c
w bieżącym katalogu i jego podkatalogach (w starszych systemach może być konieczne użycie \;
zamiast +
na końcu wiersza ( +
formularz jest szybszy, ale nie wszędzie dostępny).
find . -type f -name '*.[hc]' -exec perl -i -l -pe '…' {} +
To powiedziawszy, trzymałbym się interaktywnego edytora, jeśli potrzebujesz interakcji. Gert wskazał na to sposób w Vimie , choć wymaga otwarcia wszystkich plików, które chcesz przeszukać, co może być problemem, jeśli jest ich dużo.
W Emacs możesz to zrobić w następujący sposób:
- Zbierz nazwy plików za pomocą
M-x find-name-dired
(podaj katalog najwyższego poziomu) lub M-x find-dired
(podaj dowolny find
wiersz poleceń).
- W powstałej dired buforze, należy nacisnąć
t
, aby zaznaczyć wszystkie pliki, a następnie Q
( dired-do-query-replace-regexp
) aby przeprowadzić wymianę z prośbą o zaznaczonych plików.
s/from/to/g
z usterką formatowania po nim, zamiasts/from/to/gc
z naciskiem na to,c
jak próbowałeś pisać (nie możesz tego zrobić za pomocą Markdown, możesz to zrobić za pomocą<code>
i<strong>
tagi HTML).