Wyszukiwanie w witrynie

Jak wykonać masową zamianę tekstu w Bash w Linux


Jeśli kiedykolwiek potrzebowałeś zamienić określone słowo lub ścieżkę w setkach plików, nie jesteś sam. Byłem tam - ręcznie otwierając plik po pliku, wprowadzając tę samą zmianę w kółko. To jest powolne, nudne i podatne na błędy. Wtedy odkryłem, jak potężne może być masowe zastępowanie tekstu w Bash.

W tym wpisie wyjaśnię, jak wyszukiwać i zastępować tekst w wielu plikach jednocześnie za pomocą Bash w Linuxie, z praktycznym przykładem.

Uwaga: Ten artykuł jest napisany specjalnie dla BASH, ale zakładam, że instrukcje są takie same dla innych shelli.

Dlaczego używać Basha do masowej zamiany tekstu?

Bash jest już dostępny w większości systemów Linux i macOS (i może zostać dodany do Windows). Zawiera potężne narzędzia wiersza poleceń, takie jak grep, xargs i sed. W połączeniu te narzędzia mogą przeszukiwać tysiące plików i edytować je w kilka sekund, bez potrzeby instalowania czegokolwiek nowego.

Jeśli jesteś programistą, administratorem systemu lub po prostu kimś, kto zarządza wieloma plikami tekstowymi, Bash może zaoszczędzić ci godziny ręcznej pracy.

Znajdź i zamień tekst w plikach

Oto polecenie Bash, które znajduje i zastępuje tekst w wielu plikach jednocześnie:

grep -RiIl 'search' | xargs sed -i 's/search/replace/g'

Wyjaśnienie polecenia:

  • grep -RiIl 'search'

    • -R: Przeszukuje pliki rekurencyjnie w podkatalogach.
    • -i: Ignoruje wielkość liter (wyszukiwanie bez rozróżniania wielkości liter).
    • -I: Ignoruje pliki binarne.
    • -l: Wyświetla tylko nazwy plików, które zawierają wyszukiwany termin.
  • | xargs sed -i 's/search/replace/g'

    • xargs: Przekazuje nazwy plików do sed.
    • sed -i: Edytuje pliki w miejscu.
    • 's/search/replace/g': Zastępuje wszystkie wystąpienia „search” na „replace”.

Przykład: Aktualizacja ścieżki plików dziennika

Załóżmy, że mam katalog o nazwie ~/example_project/, który zawiera niektóre pliki konfiguracyjne i skrypty. W kilku plikach wprowadziłem na stałe ścieżkę taką jak /logs/, ale od tego czasu zmieniłem nazwę folderu na /log/.

Oto jak bym to naprawił w wielu plikach.

Krok 1: Utwórz środowisko testowe

Najpierw stwórzmy kilka testowych plików, z którymi będziemy pracować:

mkdir -p ~/example_project
cd ~/example_project

echo "Log files are stored in /logs/app1/" > config1.txt
echo "Log directory: /logs/app2/" > config2.txt
echo "No logging here" > notes.txt

Teraz sprawdź zawartość:

cat config1.txt

Zobaczysz następujące wyjście:

Log files are stored in /logs/app1/

Krok 1: Znajdź wszystkie pliki zawierające /logs/

Użyjemy grep, aby wyszukać ten ciąg:

grep -RiIl '/logs/' .

Proszę zwrócić uwagę na . (kropkę). Reprezentuje ona bieżący katalog, tzn. ~/example_project w tym przypadku.

Otrzymasz następujący wynik:

./config1.txt
./config2.txt

To potwierdza, że tylko dwa pliki wymagają zmian.

Krok 3: Zamień /logs/ na /log/ we wszystkich pasujących plikach

Teraz wykonujemy masową wymianę:

grep -RiIl '/logs/' . | xargs sed -i.bak 's|/logs/|/log/|g'

Rozbijmy to na części:

  • grep -RIl '/logs/' .: Znajdź pliki, które zawierają /logs/ w bieżącym katalogu. Tutaj . oznacza bieżący katalog
  • xargs: Przekazuje te pliki do sed.
  • sed -i.bak: Edytuje pliki w miejscu i zapisuje kopie zapasowe jako pliki .bak.
  • 's|/logs/|/log/|g': Zastępuje wszystkie wystąpienia /logs/ na /log/. s oznacza „zastąp”, a g oznacza „globalnie”, czyli zmień wszystkie wystąpienia w linii.

Uwaga: Możesz również wyraźnie podać ścieżkę do katalogu, jak poniżej:

grep -RIl '/logs/' ~/example_project | xargs sed -i.bak 's|/logs/|/log/|g'

Krok 4: Zweryfikuj zmianę

Sprawdź edytowany plik:

cat config1.txt

Przykładowy wynik:

Log files are stored in /log/app1/

Proszę zauważyć, że tekst zmienił się z /logs/app1/ na /log/app1/.

I sprawdźmy plik kopii zapasowej:

cat config1.txt.bak

Przykładowy wynik:

Log files are stored in /logs/app1/

Zauważyłeś? Plik kopii zapasowej (czyli oryginalny plik) nadal ma stary tekst /logs/app1.

Perfect! Teraz bezpiecznie zaktualizowałeś tekst i zachowałeś kopię oryginału.

Cofnij w razie potrzeby

Jeśli coś poszło nie tak, możesz przywrócić oryginały:

mv config1.txt.bak config1.txt
mv config2.txt.bak config2.txt

Czy zmiana nazwy katalogu nie jest łatwiejsza?

Możesz się zastanawiać, dlaczego po prostu nie zmienimy nazwy katalogu. Dobry punkt — tak, zmiana nazwy katalogu jest często znacznie prostsza niż wykonywanie masowej zamiany tekstu.

Na przykład, możesz pomyśleć:

mv logs log

Zrobione, prawda?

Ale oto kluczowa różnica:

Zmiana nazwy folderu zmienia tylko jego nazwę w systemie plików. Nie aktualizuje żadnego pliku, który odwołuje się do tej ścieżki.

Jeśli masz zakodowane na stałe odwołania, takie jak /logs/ w swoich skryptach, konfiguracjach lub dokumentacji, nadal będą one wskazywać na starą nazwę, a Twój system może przestać działać poprawnie lub zachowywać się nieoczekiwanie. Na przykład, jeśli plik konfiguracyjny zawiera ~/example_project/logs/error.log, ten ciąg nadal zawiera /logs/, nawet jeśli katalog teraz nazywa się /log/.

W tym właśnie miejscu pomaga masowa wymiana tekstu. Aktualizuje wszystkie te odniesienia, dzięki czemu wszystko pozostaje spójne po zmianie nazwy.

Przepisuje zakodowane na stałe ścieżki (takie jak /logs/access.log) w plikach źródłowych, skryptach, plikach konfiguracyjnych itp. Jest to przydatne, gdy w kodzie lub plikach danych zapisane są ścieżki absolutne.

Pomyśl o tym w ten sposób:

  • mv logs log → zmienia rzeczywisty folder.
  • grep + sed → aktualizuje odniesienia do tego folderu wewnątrz plików.

Są to narzędzia komplementarne, a nie wymienne.

Wniosek

Masowa zamiana tekstu w Bash to jedna z tych supermocy, których nie zdajesz sobie sprawy, że potrzebujesz — aż do momentu, gdy zaczniesz ich używać. Gdy ją opanujesz, będziesz jej używać cały czas, aby:

  • Napraw zakodowane na stałe ścieżki.
  • Zaktualizuj wartości konfiguracji.
  • Popraw błędy typograficzne w dużych projektach.
  • Przebuduj przestarzałe bazy kodu.

Jest szybki, skryptowalny i działa wszędzie tam, gdzie dostępny jest Bash. Pamiętaj tylko, aby najpierw przetestować i zrobić kopie zapasowe, jeśli nie jesteś pewien.

Czy używałeś Bash do jednoczesnej edycji wielu plików? Masz trik, którego nie omówiłem? Zostaw komentarz i podziel się swoim podejściem.

Szczególne podziękowania dla naszego czytelnika "EarBiteR" za podzielenie się tą przydatną wskazówką.

Powiązana lektura:

  • Jak wymienić tekst w wielu plikach za pomocą skryptu Bash w systemie Linux
  • 8 metod na jednoczesną zmianę nazw wielu plików w Linuksie