Znajdź i zamień tekst w wielu plikach

84

Chcę wiedzieć, jak znaleźć i zamienić określony tekst w wielu plikach, takich jak Notepad ++ w połączonym samouczku.

np .: http://cybernetnews.com/find-replace-multiple-files/

Faruk Uzun
źródło
Nie będzie miał interfejsu graficznego, ale zachęcam do zbadania sed (man sed). Jest to edytor strumieniowy, który istnieje od początku systemu UNIX.
apolinsky

Odpowiedzi:

136

Tutaj używam sed, aby zastąpić każde wystąpienie słowa „cybernetnews” słowem „cybernet” w każdym pliku z rozszerzeniem, c, w katalogu / home / user / directory /.

find /home/user/directory -name \*.c -exec sed -i "s/cybernetnews/cybernet/g" {} \;

Bardziej ogólna odmiana, w której wyszukiwanie odbywa się rekurencyjnie z katalogu wykonania i działa tylko na zwykłych, czytelnych i zapisywalnych plikach:

find ./ -type f -readable -writable -exec sed -i "s/cybernetnews/cybernet/g" {} \;
gregtczap
źródło
2
Zagłosowano na to, ponieważ jest to tak skuteczna metoda
Sabacon
4
Głosowałem, ponieważ sed jest najlepszym wyborem IMO, ale odpowiedź byłaby bardziej przydatna, gdybyś wyjaśnił składniki odpowiedzi (osobiście, nie jestem zaznajomiony z {} \;)
sequoia mcdowell
5
@sequoiamcdowell Woo! Tęskniłem za tym! Przepraszam. Nawiasy klamrowe oznaczają w zasadzie „dla każdego dopasowania”, a uciekający średnik (\;) ma zapobiegać podwójnej analizie. Nie chcemy, aby skorupa i sed kompatybilne z Bournem próbowały przeanalizować polecenie, po prostu sed.
@Christopher, jak to działa, jeśli słowo zawiera spacje takie jak cyber net news? Jak mogę to przekonwertować cyber net?
Khurshid Alam
1
@KhurshidAlam Użyj klasy znaków z przełącznikiem -e:sed -i -e "s/cyber\snet\snews/cyber net/g"
27

Edytor strumieniowy, sed, jest potężnym narzędziem do tego rodzaju pracy i jest moim pierwszym wyborem, jednak jeśli chcesz to zrobić ze zwykłego edytora tekstowego przy użyciu natywnej aplikacji opartej na Ubuntu, proponuję spojrzeć na Jedit , Jest dostępny w repozytoriach i można go zainstalować, wpisując w konsoli:

sudo apt-get install jedit

Uruchom jedit, kliknij pozycję menu wyszukiwania, na liście menu kliknij pozycję Szukaj w katalogu, zostanie wyświetlone poniższe okno dialogowe:

Okno dialogowe wyszukiwania w folderze Jedit

Jest podobny do Notepad ++ i robi to samo, wierzę, że tego właśnie chcesz.

Sabacon
źródło
Było to idealne rozwiązanie, gdy szukałem całego wiersza kodu, i wahałem się uciec od każdego znaku specjalnego wyrażenia regularnego, jeśli zrobiłbym to samo sed.
IQAndreas,
możesz zastąpić bloki kodu (takie jak HTML, JavaScript) w kilka sekund.
lepe
Nie działa to w przypadku dużej liczby plików, po kilku godzinach nie dokonano jednej wymiany, a geany zajęło kilka minut, aby znaleźć wszystkie zdarzenia. To może nie być skuteczne wyszukiwanie i zamiana, ale ładnie rozgrzało pokój.
Mark Aroni
19

Inną opcją GUI jest regexxer : zrzut ekranu regexxer

int_ua
źródło
Działa idealnie (jeśli już znasz Regex), dziękuję.
Ernest
1
Nawet jeśli nie znasz wyrażenia regularnego, możesz użyć tego narzędzia jako prostego narzędzia do wyszukiwania i zamiany ciągów znaków, które wykona zadanie za Ciebie, bez potrzeby wyrażenia regularnego ani nic takiego.
Mohd Abdul Mujib
13
perl -pi -e 's/oldtext/newtext/g' *

zastępuje każde wystąpienie oldtext przez newtext we wszystkich plikach w bieżącym folderze. Jednak będziesz musiał uciec od wszystkich znaków specjalnych Perla w oldtext i newtext za pomocą odwrotnego ukośnika.

Michael K.
źródło
9

Sprawdź u Geany , jest to idealny zamiennik NPP dla Linuksa. Możesz zrobić dokładnie to, plus możesz użyć wyrażenia regularnego.

Stefano Mtangoo
źródło
Kocham Geany! To mój ulubiony edytor i jest wystarczająco potężny.
Pisu,
1
O ile mogę stwierdzić, Geany 1.23.1 (w pakiecie z Ubuntu 13.10) pozwala na wyszukiwanie wielu plików przy użyciu wyrażenia regularnego, ale ich nie zastępuje.
Drew Noakes,
Możesz wyszukiwać i zamieniać w Geany wiele plików, jeśli otworzysz je wszystkie, a następnie za pomocą przycisku „w sesji” w oknie dialogowym Wyszukaj / Zamień.
MV.
1
Jak otwierać 5000 plików wymienionych na karcie wiadomości?
Mark Aroni
1
Ok, regexxer był właściwie tym, o co prosiłem, właśnie go pominąłem, ponieważ jego nazwa ma regex i po prostu staram się unikać cokolwiek wspólnego z regex. Ale myliłem się, i to narzędzie ma dokładnie to, co jest wymagane do wyszukiwania i wymiany.
Mohd Abdul Mujib
2

Możesz użyć tego skryptu, skopiować kod i utworzyć plik find_and_replace_in_files.sh.

Trochę go zmodyfikowałem; proszę powiedz mi swoją opinię.

# *****************************************************************************************
# find_and_replace_in_files.sh
# This script does a recursive, case sensitive directory search and replace of files
# To make a case insensitive search replace, use the -i switch in the grep call
# uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
# *****************************************************************************************

!/bin/bash
# **************** Change Variables Here ************
startdirectory="/your/start/directory"
searchterm="test"
replaceterm="test=ok!"
# **********************************************************

echo "***************************************************"
echo "* Search and Replace in Files Version 01-Aug-2012 *"
echo "***************************************************"

i=0; 

  for file in $(grep -l -R $searchterm $startdirectory)
    do
      cp $file $file.bak
      sed -e "s/$searchterm/$replaceterm/ig" $file > tempfile.tmp
      mv tempfile.tmp $file

    let i++;

      echo "Modified: " $file
    done

echo " *** All Done! *** Modified files:" $i
dimitrios
źródło
2

Innym programem jest Searchmonkey .

SearchMonkey to lekka aplikacja Gtk, której celem jest zastąpienie kłopotliwego find / grep eleganckim interfejsem użytkownika, który szybko zapewnia znaczniki pokazujące lokalizacje i liczbę dopasowanych tekstów. Celem jest zapewnienie prostego w użyciu i dostępnego narzędzia wyszukiwania dla użytkowników końcowych i twórców oprogramowania.

vrcmr
źródło
2
find . -name "*.txt" |xargs sed -i "s/searched_Text/replacement_Text/g"

działa dla mnie na Fedorze

użytkownik328359
źródło
Możesz dodać wiersz wyjaśniający, jak to się poprawia w porównaniu z askubuntu.com/a/84013/158442
mur
@muru Działa o wiele mniej sedinstancji! Jest więc znacznie szybszy pod względem czasu procesora. Ponieważ czas dostępu do pliku byłby ograniczony, myślę, że nie jest on znacznie szybszy w czasie, ale daje mniejsze obciążenie systemu. Uwaga xargsumieści wiele wierszy nazw plików w sedwierszu polecenia pojedynczego polecenia - wypełniając dostępny rozmiar bufora na podstawie długości ścieżek.
Volker Siegel,
Hmm ... jeśli to się zamknie, mógłbym zastąpić je jednym, wyjaśniającym, dlaczego jest lepszy od tego, który głosował.
Volker Siegel,
@VolkerSiegel, które można osiągnąć za pomocą +zamiast \;w find, prawda?
muru
1
@muru Być może ... Moje „sztywne narzędzie do pracy” - instynkt wyraźnie woli xargs, ale masz rację; z man find: -exec command {} +... The command line is built in much the same way that xargs.... Przypomina mi się wiersze poleceń git filter-branch...;)
Volker Siegel,
2

To bardzo proste rozwiązanie: zastąpić w wszystkie *.txtpliki w folderze string_1z string_2:

sed -i 's/string_1/string_2/g' *.txt
Helmut P.
źródło
Świetna odpowiedź! Tylko jakiś dodatek. Jeśli chcesz zastąpić ciąg w dowolnym pliku bieżącego katalogu rekurencyjnie, spróbuj tego:sed -i 's/string_1/string_2/g' $(grep -rEl 'string_1' ./)
drugan