Trova e sostituisci con sed in directory e sottodirectory


244

Eseguo questo comando per trovare e sostituire tutte le occorrenze di 'apple' con 'orange' in tutti i file nella radice del mio sito:

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

Ma non passa attraverso le sottodirectory.

Cosa c'è di sbagliato in questo comando?

Ecco alcune righe di output di find ./:

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

potresti eseguire find ./e pubblicare alcuni output di esempio? E la struttura delle directory per favore. modifica: grazie!
Jacob,

Hm la tua ricerca è corretta, funziona per me con i sottodir.
Jacob,

1
Come fai a sapere che non elabora le sottodirectory?
Carlpett,

perché dà questi errori: sed: impossibile modificare ./fpd: non un normale file sed: impossibile modificare ./fpd/font: non un normale file sed: impossibile modificare ./fpd/font/makefont: non un regula
hd.

oh ... chiedo mela e non ho trovato nulla. sono stati tutti sostituiti. ;) grazie . mi hai aperto gli occhi !!!
hd.

Risposte:


422

La tua ricerca dovrebbe apparire così per evitare di inviare nomi di directory a sed:

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

19
Potrebbe essere necessario cambiare sed -i 's/apple/orange/g'a sed -i '' 's/apple/orange/g'per fare questo lavoro.
paulmelnikow,

7
-iaccetta un argomento: l'estensione utilizzata per salvare il file temporaneo. In GNU sed sembra che non ci sia spazio tra -ie il suo argomento, ma in BSD sed c'è ... quindi BSD -i '' 's/foo/bar/'è equivalente a GNU -i 's/foo/bar/.
paulmelnikow,

20
In realtà l'aggiunta -enon funziona su Mac OS. touch a b c d eseguito dal comando precedente produce un elenco di directory in questo modo: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow,

6
Per Mac OS, questo risponde stackoverflow.com/questions/19242275/...~~V~~plural~~3rd ilRE error: illegal byte sequence
Kakoma

3
Per gli utenti di gusci di pesce, assicurati di citare le parentesi graffe vuote '{}', perché il pesce espande automaticamente le parentesi graffe vuote se non viene quotato.
Kevin Cherepski,

85

Per compiti di ricerca e sviluppo più grandi è meglio e più veloce usare grep e xargs, quindi, per esempio;

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

20
Grazie per questa risposta, è stato molto utile! Se in un repository git, è ancora più veloce usandogit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues l'

4

Questo ha funzionato per me:

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

la domanda originale non si limita ai file * .php, ce n'è anche uno .ini
knocte

Il non quotato *.phpè davvero errato; sei stato solo fortunato a non essersi espanso nella directory di partenza perché non vi era alcun file corrispondente lì.
triplo il

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

1

Dato che ci sono anche persone macOS che leggono questo (come ho fatto io), il seguente codice ha funzionato per me (il 10.14)

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

Tutte le altre risposte utilizzano -ie -enon funzionano su macOS.

fonte


0

Penso che possiamo farlo con un semplice comando a una riga

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

Fare riferimento a questa pagina .


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.