Wskazówka: Nie wykonuj poniższych czynności w drzewie kasy SVN ... spowoduje to zastąpienie magicznych plików folderów .svn.
J. Polfer,
7
o mój boże, właśnie to właśnie zrobiłem. Ale zadziałało i nie wyrządziło żadnej szkody. Co najgorszego może się zdarzyć?
J. Katzwinkel,
5
@ J.Katzwinkel: przynajmniej może uszkodzić sumy kontrolne, co może uszkodzić twoje repozytorium.
ninjagecko
3
Szybka wskazówka dla wszystkich osób używających sed: doda nowe końcowe wiersze do twoich plików. Jeśli ich nie chcesz, najpierw wykonaj polecenie zamiany znalezienia, które nie pasuje do niczego, i zatwierdź to w git. Więc zrób prawdziwy. Następnie uruchom bazę interaktywnie i usuń pierwszy.
funroll
5
Można wykluczyć katalog, takich jak git, z wynikami stosując -path ./.git -prune -osię find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0przed potokiem do xargs
devinbost
Odpowiedzi:
850
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
-print0każe findwydrukować każdy wynik oddzielony znakiem null, a nie nowym wierszem. W mało prawdopodobnym przypadku, gdy katalog zawiera pliki z nowymi liniami w nazwach, nadal pozwala to xargsna pracę z poprawnymi nazwami plików.
\( -type d -name .git -prune \)jest wyrażeniem, które całkowicie pomija wszystkie nazwane katalogi .git. Możesz łatwo go rozwinąć, jeśli używasz SVN lub masz inne foldery, które chcesz zachować - po prostu dopasuj do większej liczby nazw. Jest mniej więcej równoważny -not -path .git, ale bardziej wydajny, ponieważ zamiast sprawdzać każdy plik w katalogu, pomija go całkowicie. Jest -oto wymagane ze względu na to, jak -prunefaktycznie działa.
W OSX może wystąpić sed: 1: "...": invalid command code .problem. Wygląda na to, że opcja -i oczekuje rozszerzenia i analizuje 's/../...'polecenie. Rozwiązanie: przekaż rozszerzenie '' na opcję -i jak sed -i '' 's/....
Robert Lujo,
6
Uwaga: jeśli używasz tego w katalogu i zastanawiasz się, dlaczego svn stnie pokazuje żadnych zmian, dzieje się tak dlatego, że zmodyfikowałeś również pliki w katalogach .svn! Użyj find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'zamiast tego.
ACK_stoverflow 26.09.13
57
Uważaj też, jeśli korzystasz z repozytorium git. Myślałem, że jestem mądry, testując to na wyraźnej gałęzi, aby móc cofnąć się, jeśli zrobiłoby to coś złego, ale zamiast tego uszkodził mój indeks git.
Ciryon
13
Użyj tego, grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'aby uniknąć edycji niepowiązanych plików (sed może zmienić kodowanie plików).
caiguanhao
6
„ale zamiast tego zepsułem mój indeks git.” Nie przejmuj się zbytnio tym, co możesz zrobić, find .git ... | ... 'sed -i s/(the opposite from before)/g'aby naprawić indeks git
Massey101
259
Uwaga : Nie uruchamiaj tego polecenia w folderze zawierającym repozytorium git - zmiany na .git mogą uszkodzić indeks git.
find /home/www/-type f -exec \
sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
W porównaniu do innych odpowiedzi tutaj jest to prostsze niż większość i używa sed zamiast perla, o co zadawano oryginalne pytanie.
Pamiętaj, że jeśli korzystasz z BSD sed (w tym na Mac OS X), musisz podać jawnie pusty ciąg argumentu -iopcji sed . tj .: sed -i '' 's/original/replacement/g'
Nathan Craike
2
@JohnZwinck Mój błąd, brakowało +. O dziwo, rozwiązanie Nikity działa dla mnie szybciej.
Sam
6
@AoeAoe: +Znacznie zmniejsza liczbę spawnowanych sedprocesów. Jest bardziej wydajny.
John Zwinck
4
Jak mogę to bezpiecznie zrobić w folderze z repozytorium git?
Hatszepsut
20
Jest to bezpieczne, aby wykonać na folderze zawierającym git repo jeśli wykluczyć repo z wyników znajdują się: find . -not -path '*/\.git*' -type f ....
Dale Anderson
210
Najprostszym sposobem jest dla mnie
grep -rl oldtext .| xargs sed -i 's/oldtext/newtext/g'
@Anatoly: tylko jedno pytanie: jak mogę wykluczyć pliki binarne (pliki wykonywalne) ?
user2284570,
3
@ user2284570 Użyj flag -Ilub --binary-file=without-matchgrep.
Zéychin
34
Działa to szczególnie dobrze, gdy trzeba wykluczyć katalogi, jak w przypadku .svn. Na przykład:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
phyatt
11
brew install gnu-sedi używaj gsedw OSX, aby uniknąć bólu.
P i
1
Chłopaki proszę uwagę, jeśli projekt jest git wersji, użyj zamiast tego: git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'. w ogóle nie fajnie jest pierdolić swój .gitkatalog
Paolo
61
Wszystkie triki są prawie takie same, ale podoba mi się ten:
find <mydir>-type f -exec sed -i 's/<string1>/<string2>/g'{}+
find <mydir>: wyszukaj w katalogu.
-type f:
Plik jest typu: zwykły plik
-exec command {} +:
Ten wariant akcji -exec uruchamia określone polecenie na wybranych plikach, ale linia poleceń jest budowana przez dołączenie każdej wybranej nazwy pliku na końcu; całkowita liczba wywołań polecenia będzie znacznie mniejsza niż liczba dopasowanych plików. Wiersz poleceń jest budowany w taki sam sposób, jak xargs buduje wiersze poleceń. W poleceniu dozwolona jest tylko jedna instancja „{}”. Polecenie jest wykonywane w katalogu startowym.
@ I159 Czy ta odpowiedź nie jest identyczna z odpowiedzią Johna Zwincka ?
Przywróć Monikę, proszę,
1
@ user2284570 Pojęcie „pliku binarnego” nie jest całkowicie dobrze zdefiniowane. Możesz użyć filepolecenia, aby spróbować określić typ każdego pliku, ale przypadkowe zmiany w jego wyniku mogą być nieco oszałamiające. Opcja -I(aka --mime) nieco pomaga lub --mime-typejeśli masz taką opcję . Jak dokładnie przeformułować ten schludny jednowierszowy, aby to zrobić, niestety nie wchodzi w zakres tego małego pola komentarza. Może opublikujesz osobne pytanie, jeśli potrzebujesz pomocy? (Być może zatem dodaj tutaj komentarz z linkiem.)
tripleee
1
najczystsza odpowiedź! dzięki kolego
jukerok
39
cd /home/www && find .-type f -print0 |
xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'
Jestem ciekaw, czy istnieje powód, aby użyć -print0i xargszamiast -execlub -execdir?
Philipp
4
Jest: z „man find”: Określone polecenie jest uruchamiane raz dla każdego dopasowanego pliku. Oznacza to, że jeśli w katalogu / home / www znajduje się 2000 plików, wówczas „find ... -exec ...” spowoduje 2000 wywołań perla; podczas gdy „znajdź ... | xargs ... 'wywoła perla tylko raz lub dwa razy (przy założeniu ARG_MAX o wielkości około 32 KB i średniej długości nazwy pliku wynoszącej 20).
Zatrudniony rosyjski
2
@Employed Russian: dlatego użyjesz find -exec command {} +- pozwala uniknąć nadmiernego wywoływania polecenia, takiego jak xargs, ale bez osobnego procesu.
John Zwinck,
2
Na jakiej platformie? Rozwiązanie xargs jest przenośne, „magiczne” wywołania „find ... -exec”, które nie wywołują podprocesu dla każdego znalezionego pliku, nie są.
Zatrudniony rosyjski
4
@EmployedRussian, find -exec ... {} +został określony przez POSIX od 2006 roku.
UWAGA : Jeśli jest zbyt wiele plików do przetworzenia, otrzymasz Argument list too long. Obejście - zastosowanie find -execlub xargsrozwiązanie opisane powyżej.
workaroundPowinna być preferowana składnia we wszystkich przypadkach.
Przywróć Monikę, proszę,
1
Problem z zastępowaniem poleceń $(find...)polega na tym, że powłoka nie ma możliwości obsługi nazw plików z białymi spacjami lub innymi metaznakami powłoki. Jeśli wiesz, że to nie jest problem, to podejście jest w porządku; ale mamy zbyt wiele pytań, w których ludzie nie byli ostrzegani o tym problemie lub nie rozumieli ostrzeżenia.
Dobry pomysł, jeśli pracujesz w repozytorium git, ponieważ nie ryzykujesz nadpisania .git / content (jak podano w komentarzach do innej odpowiedzi).
mahemoff
1
Dzięki, używam go jako funkcji bash refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }Użycie, na przykład do zastąpienia słowa „słowem” słowem „miecz”: refactor word swordnastępnie sprawdź, co to zrobiło git diff.
Paul Rougieux,
16
Aby ograniczyć rekursywnie pliki sed, możesz grepdla instancji ciągu:
grep -rl <oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Jeśli uruchomisz man grep, zauważysz, że możesz również zdefiniować --exlude-dir="*.git"flagę, jeśli chcesz pominąć przeszukiwanie katalogów .git, unikając problemów z indeksem git, jak inni uprzejmie zauważyli.
Prowadzi Cię do:
grep -rl --exclude-dir="*.git"<oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Rozsądniej użyć git-grep„s -zopcję razem z xargs -0.
gniourf_gniourf
git grepoczywiście ma to sens tylko w przypadku gitrepo. Ogólny zamiennik byłby grep -r.
tripleee
@gniourf_gniourf Czy potrafisz wyjaśnić?
Petr Peller
2
@PetrPeller: z -z, git-grepoddzieli pola wyjściowe bajtami pustymi zamiast znaków nowej linii; i with -0, xargsodczyta dane wejściowe oddzielone pustymi bajtami zamiast pustych znaków (i nie rób dziwnych rzeczy z cudzysłowami). Więc jeśli nie chcesz polecenie złamać jeśli nazwy plików zawierają spacje, cytaty lub inne znaki śmieszne, polecenie to: git grep -z -l 'original_text' | xargs -0 sed ....
gniourf_gniourf
10
find /home/www/-type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
find /home/www/ -type f wyświetli listę wszystkich plików w / home / www / (i jego podkatalogach). Flaga „-exec” informuje find, aby uruchomić następującą komendę dla każdego znalezionego pliku.
to polecenie uruchamiane na plikach (wiele na raz). Zostanie {}zastąpiony przez nazwy plików. Na +końcu polecenia mówi findo zbudowaniu jednego polecenia dla wielu nazw plików.
Per find stronie : „Linia poleceń jest budowana w taki sam sposób, jak xargs buduje swoje linie poleceń”.
W ten sposób można osiągnąć swój cel (i obsługiwać nazwy plików zawierające spacje) bez użycia xargs -0lub -print0.
Ack-grep jest bardzo wydajny w wyszukiwaniu odpowiednich plików. To polecenie zastąpiło ~ 145 000 plików, a inne zajęły tak długo, że nie mogłem się doczekać ich zakończenia.
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Wydaje mi się, że większość ludzi nie wie, że mogą przesłać coś do „podczas odczytu pliku” i pozwala to uniknąć tych nieprzyjemnych argumentów -print0, jednocześnie zachowując spacje w nazwach plików.
Dalsze dodawanie echoprzed sedem pozwala zobaczyć, jakie pliki zmienią się przed wykonaniem tego.
Powód -print0jest przydatny, ponieważ obsługuje przypadki, które while readpo prostu nie są w stanie obsłużyć - nowa linia jest poprawnym znakiem w nazwie pliku uniksowego, więc aby kod był całkowicie niezawodny, musi również radzić sobie z takimi nazwami plików. (Ponadto, chcesz read -runiknąć niektórych read
przykrych
Ponadto sedjest to brak opcji, jeśli nie ma żadnych dopasowań, więc grepnie jest to naprawdę konieczne; chociaż jest to przydatna optymalizacja, aby uniknąć przepisywania plików, które nie zawierają żadnych dopasowań, jeśli masz ich wiele lub chcesz niepotrzebnie aktualizować znaczniki daty na plikach.
tripleee
5
Możesz użyć awk, aby rozwiązać ten problem, jak poniżej,
Działa na MacO bez żadnych problemów! Wszystkie sedpolecenia bazowe nie powiodły się, gdy pliki binarne zostały uwzględnione, nawet przy specyficznych ustawieniach systemu OSX.
Jankapunkt
Ostrożnie ... to wybuchnie, jeśli którykolwiek ze findzwrotów plików będzie miał spację w swoich nazwach! Jest o wiele bezpieczniejszy w użyciu while read: stackoverflow.com/a/9612560/1938956
Soren Bjornstad
4
Spróbuj tego:
sed -i 's/subdomainA/subdomainB/g'`grep -ril 'subdomainA' *`
Cześć @RikHic, fajna wskazówka - myślałem o czymś takim; niestety, powyższe formatowanie nie wyszło dobrze :) Więc spróbuję z tagiem wstępnym (nie działa) - więc z uciekającymi się backtickami: sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*` - To wciąż nie wygląda zbyt dobrze, ale powinno przetrwać copypaste :) Pozdrawiam!
sdaau,
4
#!/usr/local/bin/bash -x
find */home/www -type f |while read files
do
sedtest=$(sed -n '/^/,/$/p'"${files}"| sed -n '/subdomainA/p')if["${sedtest}"]then
sed s'/subdomainA/subdomainB/'g "${files}">"${files}".tmp
mv "${files}".tmp "${files}"fidone
Jak uciekasz przed ukośnikami /? Na przykład chcę zastąpić adresy IP: xxx.xxx.xxx.xxxforxxx.xxx.xxx.xxx/folder
Pathros
Możesz uciec /z \. Na przykład:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
J.Hpour
3
Jeśli nie masz nic przeciwko używaniu vimrazem z narzędziami greplub findnarzędziami, możesz śledzić odpowiedź udzieloną przez użytkownika Gert w tym linku -> Jak zamienić tekst w hierarchii dużych folderów? .
Oto oferta:
rekurencyjnie grep dla ciągu, który chcesz zastąpić w określonej ścieżce, i weź tylko pełną ścieżkę pasującego pliku. (to by było $(grep 'string' 'pathname' -Rl).
(opcjonalnie) jeśli chcesz wykonać kopię zapasową tych plików w scentralizowanym katalogu, możesz użyć tego również: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
po tym możesz dowolnie edytować / zamieniać według vimschematu podobnego do tego podanego na podanym linku:
• Będzie edytować tylko pliki z rozszerzeniem .slsw bieżącym katalogu
• .należy uciec, aby upewnić się, sedże nie ocenia ich jako „żadnej postaci”
• ,jest używany jako sedseparator zamiast zwykłego/
Pamiętaj też, że jest to edycja szablonu Jinja, aby przekazać variableścieżkę import(ale to nie jest temat).
Najpierw sprawdź, czy polecenie sed robi to, co chcesz (spowoduje to wydrukowanie zmian tylko na standardowe wyjście, nie spowoduje to zmiany plików):
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
W razie potrzeby edytuj polecenie sed, gdy będziesz gotowy do wprowadzenia zmian:
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed -i '''s,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
Zauważ, że -i ''w sed polecenia, nie chcę, aby utworzyć kopię zapasową oryginalnych plików (jak wyjaśniono w w miejscu edycji z sed na OSX lub w komentarzu Roberta LUJO w tej stronie).
plus jeden za „'*. [c | cc | cp | cpp | m | mm | h]' '
FractalSpace
2
Oto wersja, która powinna być bardziej ogólna niż większość; nie wymaga na przykład find( duzamiast tego używania ). To wymaga xargs, które można znaleźć tylko w niektórych wersjach Planu 9 (np. 9front).
du -a | awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Jeśli chcesz dodać filtry, takie jak rozszerzenia plików, użyj grep:
du -a | grep "\.scala$"| awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Nawiasy wydają się zbyteczne. Wcześniej występował błąd formatowania, który uniemożliwiał jego użycie (renderowanie Markdown zjadłoby niektóre znaki z wyrażenia regularnego).
tripleee
1
Używanie kombinacji grepised
for pp in $(grep -Rl looking_for_string)do
sed -i 's/looking_for_string/something_other/g'"${pp}"done
@tripleee Zmodyfikowałem to trochę. W tym przypadku dane wyjściowe dla grep -Rl patternwygenerowanej przez polecenia listy plików, w których znajduje się wzorzec. Pliki nie są odczytywane w forpętli.
Paweł
Co? Nadal masz forpętlę; jeśli jakakolwiek zwrócona nazwa pliku zawiera białe znaki, nie będzie działać poprawnie, ponieważ powłoka tokenizuje forlistę argumentów. Ale potem używasz zmiennej nazwy pliku bez cudzysłowów w pętli, więc zamiast tego pękłaby tam, jeśli to naprawisz. Poprawienie pozostałych błędów sprawi, że twoje będą identyczne z odpowiedzią @ MadMan2064.
tripleee
@tripleee tak, to prawda, tęskniłem za tym.
Paweł
1
Aby zamienić wszystkie wystąpienia w repozytorium git, możesz użyć:
git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
Zobacz Lista plików w lokalnym repozytorium git? dla innych opcji, aby wyświetlić listę wszystkich plików w repozytorium. Te -zopcje mówi git oddzielić nazwy plików z bajtem zerowym, który zapewnia, że xargs(z opcją -0) można oddzielić nazwy plików, nawet jeśli zawierają one spacje lub etażerka.
-path ./.git -prune -o
sięfind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
przed potokiem do xargsOdpowiedzi:
-print0
każefind
wydrukować każdy wynik oddzielony znakiem null, a nie nowym wierszem. W mało prawdopodobnym przypadku, gdy katalog zawiera pliki z nowymi liniami w nazwach, nadal pozwala toxargs
na pracę z poprawnymi nazwami plików.\( -type d -name .git -prune \)
jest wyrażeniem, które całkowicie pomija wszystkie nazwane katalogi.git
. Możesz łatwo go rozwinąć, jeśli używasz SVN lub masz inne foldery, które chcesz zachować - po prostu dopasuj do większej liczby nazw. Jest mniej więcej równoważny-not -path .git
, ale bardziej wydajny, ponieważ zamiast sprawdzać każdy plik w katalogu, pomija go całkowicie. Jest-o
to wymagane ze względu na to, jak-prune
faktycznie działa.Aby uzyskać więcej informacji, zobacz
man find
.źródło
sed: 1: "...": invalid command code .
problem. Wygląda na to, że opcja -i oczekuje rozszerzenia i analizuje's/../...'
polecenie. Rozwiązanie: przekaż rozszerzenie '' na opcję -i jaksed -i '' 's/...
.svn st
nie pokazuje żadnych zmian, dzieje się tak dlatego, że zmodyfikowałeś również pliki w katalogach .svn! Użyjfind . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'
zamiast tego.grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'
aby uniknąć edycji niepowiązanych plików (sed może zmienić kodowanie plików).find .git ... | ... 'sed -i s/(the opposite from before)/g'
aby naprawić indeks gitUwaga : Nie uruchamiaj tego polecenia w folderze zawierającym repozytorium git - zmiany na .git mogą uszkodzić indeks git.
W porównaniu do innych odpowiedzi tutaj jest to prostsze niż większość i używa sed zamiast perla, o co zadawano oryginalne pytanie.
źródło
-i
opcji sed . tj .:sed -i '' 's/original/replacement/g'
+
Znacznie zmniejsza liczbę spawnowanychsed
procesów. Jest bardziej wydajny.find . -not -path '*/\.git*' -type f ...
.Najprostszym sposobem jest dla mnie
źródło
-I
lub--binary-file=without-match
grep..svn
. Na przykład:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
brew install gnu-sed
i używajgsed
w OSX, aby uniknąć bólu.git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
. w ogóle nie fajnie jest pierdolić swój.git
katalogWszystkie triki są prawie takie same, ale podoba mi się ten:
find <mydir>
: wyszukaj w katalogu.-type f
:-exec command {} +
:źródło
file
polecenia, aby spróbować określić typ każdego pliku, ale przypadkowe zmiany w jego wyniku mogą być nieco oszałamiające. Opcja-I
(aka--mime
) nieco pomaga lub--mime-type
jeśli masz taką opcję . Jak dokładnie przeformułować ten schludny jednowierszowy, aby to zrobić, niestety nie wchodzi w zakres tego małego pola komentarza. Może opublikujesz osobne pytanie, jeśli potrzebujesz pomocy? (Być może zatem dodaj tutaj komentarz z linkiem.)źródło
-print0
ixargs
zamiast-exec
lub-execdir
?find -exec command {} +
- pozwala uniknąć nadmiernego wywoływania polecenia, takiego jak xargs, ale bez osobnego procesu.find -exec ... {} +
został określony przez POSIX od 2006 roku.Dla mnie najłatwiejszym rozwiązaniem do zapamiętania jest https://stackoverflow.com/a/2113224/565525 , tj .:
UWAGA :
-i ''
rozwiązuje problem OSXsed: 1: "...": invalid command code .
UWAGA : Jeśli jest zbyt wiele plików do przetworzenia, otrzymasz
Argument list too long
. Obejście - zastosowaniefind -exec
lubxargs
rozwiązanie opisane powyżej.źródło
workaround
Powinna być preferowana składnia we wszystkich przypadkach.$(find...)
polega na tym, że powłoka nie ma możliwości obsługi nazw plików z białymi spacjami lub innymi metaznakami powłoki. Jeśli wiesz, że to nie jest problem, to podejście jest w porządku; ale mamy zbyt wiele pytań, w których ludzie nie byli ostrzegani o tym problemie lub nie rozumieli ostrzeżenia.Dla każdego, kto korzysta ze srebrnego wyszukiwarki (
ag
)Ponieważ ag domyślnie ignoruje pliki / foldery git / hg / svn, uruchomienie w repozytorium jest bezpieczne.
źródło
Jeden miły oneliner jako dodatek. Używanie git grep.
źródło
refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }
Użycie, na przykład do zastąpienia słowa „słowem” słowem „miecz”:refactor word sword
następnie sprawdź, co to zrobiłogit diff
.Aby ograniczyć rekursywnie pliki
sed
, możeszgrep
dla instancji ciągu:Jeśli uruchomisz
man grep
, zauważysz, że możesz również zdefiniować--exlude-dir="*.git"
flagę, jeśli chcesz pominąć przeszukiwanie katalogów .git, unikając problemów z indeksem git, jak inni uprzejmie zauważyli.Prowadzi Cię do:
źródło
Ten jest kompatybilny z repozytoriami git i nieco prostszy:
Linux:
Prochowiec:
(Dzięki http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ )
źródło
git-grep
„s-z
opcję razem zxargs -0
.git grep
oczywiście ma to sens tylko w przypadkugit
repo. Ogólny zamiennik byłbygrep -r
.-z
,git-grep
oddzieli pola wyjściowe bajtami pustymi zamiast znaków nowej linii; i with-0
,xargs
odczyta dane wejściowe oddzielone pustymi bajtami zamiast pustych znaków (i nie rób dziwnych rzeczy z cudzysłowami). Więc jeśli nie chcesz polecenie złamać jeśli nazwy plików zawierają spacje, cytaty lub inne znaki śmieszne, polecenie to:git grep -z -l 'original_text' | xargs -0 sed ...
.find /home/www/ -type f
wyświetli listę wszystkich plików w / home / www / (i jego podkatalogach). Flaga „-exec” informuje find, aby uruchomić następującą komendę dla każdego znalezionego pliku.to polecenie uruchamiane na plikach (wiele na raz). Zostanie
{}
zastąpiony przez nazwy plików. Na+
końcu polecenia mówifind
o zbudowaniu jednego polecenia dla wielu nazw plików.Per
find
stronie : „Linia poleceń jest budowana w taki sam sposób, jak xargs buduje swoje linie poleceń”.W ten sposób można osiągnąć swój cel (i obsługiwać nazwy plików zawierające spacje) bez użycia
xargs -0
lub-print0
.źródło
Właśnie tego potrzebowałem i nie byłem zadowolony z szybkości dostępnych przykładów. Więc wymyśliłem własne:
Ack-grep jest bardzo wydajny w wyszukiwaniu odpowiednich plików. To polecenie zastąpiło ~ 145 000 plików, a inne zajęły tak długo, że nie mogłem się doczekać ich zakończenia.
źródło
grep -ril 'subdomainA' *
nie jest tak szybki jakgrep -Hr 'subdomainA' * | cut -d: -f1
.Prosta metoda, jeśli chcesz wykluczyć katalogi (
--exclude-dir=.svn
), a także może mieć nazwy plików ze spacjami (używając 0Byte zgrep -Z
ixargs -0
źródło
Najprostszy sposób na zamianę ( wszystkie pliki, katalog, rekurencyjne )
Uwaga: Czasami może być konieczne zignorowanie niektórych ukrytych plików, np.
.git
Możesz użyć powyższej komendy.Jeśli chcesz dołączyć ukryte pliki,
W obu przypadkach ciąg
foo
zostanie zastąpiony nowym ciągiembar
źródło
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Wydaje mi się, że większość ludzi nie wie, że mogą przesłać coś do „podczas odczytu pliku” i pozwala to uniknąć tych nieprzyjemnych argumentów -print0, jednocześnie zachowując spacje w nazwach plików.
Dalsze dodawanie
echo
przed sedem pozwala zobaczyć, jakie pliki zmienią się przed wykonaniem tego.źródło
-print0
jest przydatny, ponieważ obsługuje przypadki, którewhile read
po prostu nie są w stanie obsłużyć - nowa linia jest poprawnym znakiem w nazwie pliku uniksowego, więc aby kod był całkowicie niezawodny, musi również radzić sobie z takimi nazwami plików. (Ponadto, chceszread -r
uniknąć niektórychread
sed
jest to brak opcji, jeśli nie ma żadnych dopasowań, więcgrep
nie jest to naprawdę konieczne; chociaż jest to przydatna optymalizacja, aby uniknąć przepisywania plików, które nie zawierają żadnych dopasowań, jeśli masz ich wiele lub chcesz niepotrzebnie aktualizować znaczniki daty na plikach.Możesz użyć awk, aby rozwiązać ten problem, jak poniżej,
mam nadzieję, że ci to pomoże !!!
źródło
sed
polecenia bazowe nie powiodły się, gdy pliki binarne zostały uwzględnione, nawet przy specyficznych ustawieniach systemu OSX.find
zwrotów plików będzie miał spację w swoich nazwach! Jest o wiele bezpieczniejszy w użyciuwhile read
: stackoverflow.com/a/9612560/1938956Spróbuj tego:
źródło
sed -i 's/subdomainA/subdomainB/g'
`grep -ril 'subdomainA' /home/www/*
` - To wciąż nie wygląda zbyt dobrze, ale powinno przetrwać copypaste :) Pozdrawiam!źródło
Zgodnie z tym postem na blogu:
źródło
/
? Na przykład chcę zastąpić adresy IP:xxx.xxx.xxx.xxx
forxxx.xxx.xxx.xxx/folder
/
z \. Na przykład:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
Jeśli nie masz nic przeciwko używaniu
vim
razem z narzędziamigrep
lubfind
narzędziami, możesz śledzić odpowiedź udzieloną przez użytkownika Gert w tym linku -> Jak zamienić tekst w hierarchii dużych folderów? .Oto oferta:
rekurencyjnie grep dla ciągu, który chcesz zastąpić w określonej ścieżce, i weź tylko pełną ścieżkę pasującego pliku. (to by było
$(grep 'string' 'pathname' -Rl)
.(opcjonalnie) jeśli chcesz wykonać kopię zapasową tych plików w scentralizowanym katalogu, możesz użyć tego również:
cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
po tym możesz dowolnie edytować / zamieniać według
vim
schematu podobnego do tego podanego na podanym linku::bufdo %s#string#replacement#gc | update
źródło
Trochę starej szkoły, ale działało to na OS X.
Jest kilka trików:
• Będzie edytować tylko pliki z rozszerzeniem
.sls
w bieżącym katalogu•
.
należy uciec, aby upewnić się,sed
że nie ocenia ich jako „żadnej postaci”•
,
jest używany jakosed
separator zamiast zwykłego/
Pamiętaj też, że jest to edycja szablonu Jinja, aby przekazać
variable
ścieżkęimport
(ale to nie jest temat).Najpierw sprawdź, czy polecenie sed robi to, co chcesz (spowoduje to wydrukowanie zmian tylko na standardowe wyjście, nie spowoduje to zmiany plików):
W razie potrzeby edytuj polecenie sed, gdy będziesz gotowy do wprowadzenia zmian:
Zauważ, że
-i ''
w sed polecenia, nie chcę, aby utworzyć kopię zapasową oryginalnych plików (jak wyjaśniono w w miejscu edycji z sed na OSX lub w komentarzu Roberta LUJO w tej stronie).Szczęśliwi ludzie z sedingu!
źródło
aby uniknąć zmiany
ale nadal
(może nie jest dobry pomysł na rootowanie domeny)
źródło
Po prostu używam bluzek:
źródło
Oto wersja, która powinna być bardziej ogólna niż większość; nie wymaga na przykład
find
(du
zamiast tego używania ). To wymagaxargs
, które można znaleźć tylko w niektórych wersjach Planu 9 (np. 9front).Jeśli chcesz dodać filtry, takie jak rozszerzenia plików, użyj
grep
:źródło
Dla Qshell (qsh) na IBMi, nie bash jak oznaczono OP.
Ograniczenia poleceń qsh:
Zatem rozwiązanie w qsh:
Ostrzeżenia:
źródło
for
.Jeśli chcesz użyć tego bez całkowitego zniszczenia repozytorium SVN, możesz powiedzieć „znajdź”, aby zignorował wszystkie ukryte pliki, wykonując:
źródło
Używanie kombinacji
grep
ised
źródło
grep -Rl pattern
wygenerowanej przez polecenia listy plików, w których znajduje się wzorzec. Pliki nie są odczytywane wfor
pętli.for
pętlę; jeśli jakakolwiek zwrócona nazwa pliku zawiera białe znaki, nie będzie działać poprawnie, ponieważ powłoka tokenizujefor
listę argumentów. Ale potem używasz zmiennej nazwy pliku bez cudzysłowów w pętli, więc zamiast tego pękłaby tam, jeśli to naprawisz. Poprawienie pozostałych błędów sprawi, że twoje będą identyczne z odpowiedzią @ MadMan2064.Aby zamienić wszystkie wystąpienia w repozytorium git, możesz użyć:
Zobacz Lista plików w lokalnym repozytorium git? dla innych opcji, aby wyświetlić listę wszystkich plików w repozytorium. Te
-z
opcje mówi git oddzielić nazwy plików z bajtem zerowym, który zapewnia, żexargs
(z opcją-0
) można oddzielić nazwy plików, nawet jeśli zawierają one spacje lub etażerka.źródło
źródło
awk
/sed
, ale Perl jest powszechny (z wyjątkiem systemów wbudowanych / tylko z zajęty).aby zmienić wiele plików (i zapisać kopię zapasową jako
*.bak
):weźmie wszystkie pliki z katalogu i zamieni na
|
x o nazwie „ciasto Perla” (łatwe jak ciasto)źródło