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 dosed.
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.txtTeraz sprawdź zawartość:
cat config1.txtZobaczysz 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.txtTo 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 katalogxargs: Przekazuje te pliki dosed.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/.soznacza „zastąp”, agoznacza „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.txtPrzykł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.txtCzy 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 logZrobione, 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