2009-02-09 10 views
33

jaki jest najlepszy sposób na zrobienie tego? Nie jestem wojownikiem z linii poleceń, ale myślałem, że istnieje sposób na użycie grepa i kota.Najlepszy sposób na znalezienie/zastąpienie w kilku plikach?

Chcę tylko zastąpić ciąg występujący w folderze i podfolderach. jaki jest najlepszy sposób na zrobienie tego? Używam ubuntu, jeśli to ma znaczenie.

-d

+0

Zostawiamy to łącze tutaj: http://stackoverflow.com/questions/102083/whats-the-best-tool-to-find-and-replace-regular-regularses-over-multiple-files –

Odpowiedz

36
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Pierwsza część to polecenie Znajdź, aby znaleźć pliki, które chcesz zmienić. Być może będziesz musiał odpowiednio to zmienić. Komenda "xargs" pobiera każdy znaleziony plik i stosuje do niego polecenie "sed". Polecenie "sed" pobiera każde wystąpienie "z" i zastępuje je "do". To standardowe wyrażenie regularne, więc zmodyfikuj je tak, jak potrzebujesz.

Jeśli korzystasz z oprogramowania svn uwaga. Twoje .svn-katalogi będą również wyszukiwane i zastępowane. Trzeba wykluczyć tych, na przykład tak:

find . ! -regex ".*[/]\.svn[/]?.*" -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

lub

find . -name .svn -prune -o -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

+0

Nie wydaje się, że to polecenie jest recursing do podkatalogów. Czy jest coś, co robię źle? – blackrobot

+0

Co sprawia, że ​​myślisz, że nie powraca do katalogów? –

+0

pliki tekstowe w podkatalogach nie wprowadzają zmian. chcę to zrobić: zmienić wystąpienia some.ip.address na stronie somewebsite.com we wszystkich podkatalogach. – blackrobot

37

Jak powiedział Paul, chcesz najpierw znaleźć pliki, które chcesz edytować, a następnie edytować je. Alternatywą dla korzystania znalezisko jest użycie GNU grep (domyślnie w Ubuntu), np:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Można również użyć ack-grep (sudo apt-get install ack-grep lub odwiedzić http://petdance.com/ack/), a także, jeśli wiesz, że chcesz tylko określonego typu pliku i chcesz zignorować rzeczy w katalogach kontroli wersji. na przykład, jeśli chcą tylko pliki tekstowe,

ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g' 
# `from` here is an arbitrary commonly occurring keyword 

alternatywa do stosowania sed jest użycie Perla, który może przetwarzać wiele plików za polecenie, np

grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g' 

Tutaj Perl dowiaduje się zmieniać w miejsce, tworząc plik .bak jako pierwszy.

Możesz łączyć dowolne lewe strony rury z prawymi stronami, w zależności od swoich preferencji.

+0

Możesz ominąć katalogi kontroli wersji w "find" za pomocą polecenia "-prune". Na przykład "find. -name RCS -prune -o -type f -print0" –

+0

Prawda, chociaż wymaga mniejszego potencjału umysłowego, aby narzędzie takie jak ACK poradziło sobie z nim. –

+0

ack akceptuje również opcję '--print0', aby użyć null jako separatora między nazwami plików, więc polecenie ack wyglądałoby tak:' ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g''' –

3

Alternatywą sed korzysta rpl (np dostępną http://rpl.sourceforge.net/ lub dystrybucji GNU/Linux), jak rpl --recursive --verbose --whole-words 'F' 'A' grades/

14

dorzucę inny przykład dla ludzi stosujących Ag, The Silver Searcher zrobić find/zastąpić operacji na wielu plikach .

Kompletny przykład:

ag -l "search string" | xargs sed -i '' -e 's/from/to/g' 

Jeśli łamiemy to na dół, co mamy jest:

# returns a list of files containing matching string 
ag -l "search string" 

Następnie mamy:

# consume the list of piped files and prepare to run foregoing command 
# for each file delimited by newline 
xargs 

Wreszcie polecenie wymiana łańcuch :

# -i '' means edit files in place and the '' means do not create a backup 
# -e 's/from/to/g' specifies the command to run, in this case, 
# global, search and replace 

sed -i '' -e 's/from/to/g' 
Powiązane problemy