Znajdź i zamień na sed w katalogu i podkatalogach


244

Uruchamiam to polecenie, aby znaleźć i zastąpić wszystkie wystąpienia „jabłka” słowem „pomarańczowy” we wszystkich plikach w katalogu głównym mojej witryny:

find ./ -exec sed -i 's/apple/orange/g' {} \;

Ale nie przechodzi przez podkatalogi.

Co jest nie tak z tym poleceniem?

Oto kilka linii wyników find ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php

czy możesz uruchomić find ./i opublikować przykładowe wyniki? I proszę o strukturę katalogów. edycja: dzięki!
Jacob

Hm, twoje znalezisko jest poprawne, działa dla mnie z podkatalogami.
Jacob

1
Skąd wiesz, że nie przetwarza podkatalogów?
carlpett

ponieważ daje następujące błędy: sed: nie można edytować ./fpd: nie jest to zwykły plik sed: nie można edytować ./fpd/font: nie jest zwykły plik sed: nie można edytować ./fpd/font/makefont: nie regula
hd.

och ... żałuję jabłka i nic nie znaleziono. wszystkie zostały zastąpione. ;) Dziękuję Ci . otworzyłeś mi oczy !!!
hd.

Odpowiedzi:


422

Twoje znalezisko powinno wyglądać tak, aby uniknąć wysyłania nazw katalogów do sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;

19
Być może trzeba zmienić sed -i 's/apple/orange/g', aby sed -i '' 's/apple/orange/g'do tej pracy.
paulmelnikow

7
-iprzyjmuje argument: rozszerzenie użyte do zapisania pliku tymczasowego. W GNU sed wygląda na to, że nie ma między nimi spacji -i, ale w BSD sed jest… więc BSD -i '' 's/foo/bar/'jest równoważne z GNU -i 's/foo/bar/.
paulmelnikow

20
W rzeczywistości dodawanie -enie działa w systemie Mac OS. touch a b c d enastępnie powyżej polecenie tworzy katalog z listą tak: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow

6
W przypadku systemu Mac OS to odpowiedzi stackoverflow.com/questions/19242275/... theRE error: illegal byte sequence
kakoma

3
W przypadku użytkowników skorupy ryb pamiętaj o cytowaniu pustych nawiasów klamrowych '{}', ponieważ ryba automatycznie rozszerza puste nawiasy klamrowe, jeśli nie są cytowane.
Kevin Cherepski,

84

W przypadku większych zadań s & r lepiej i szybciej jest używać grep i xargs, więc na przykład;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'

20
Dzięki za tę odpowiedź, była bardzo pomocna! W repozytorium git korzystanie z niego jest jeszcze szybszegit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues,

4

To działało dla mnie:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;

oryginalne pytanie nie ogranicza się do plików * .php, jest też jeden .ini
knocte

Cudzysłowy *.phpjest naprawdę niepoprawny; po prostu miałeś szczęście, że nie został rozwinięty w katalogu startowym, ponieważ nie było tam żadnych pasujących plików.
tripleee

3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"

1

Ponieważ są też ludzie macOS czytający ten (tak jak ja), poniższy kod działał dla mnie (10.14)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @

Wszystkie pozostałe odpowiedzi używają -ii -enie działają w systemie macOS.

Źródło


0

Myślę, że możemy to zrobić za pomocą prostej linii w jednym wierszu

for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done

Sprawdź tę stronę .


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.