Comando grep per trovare file contenenti stringhe di testo e spostarli


15

Sono in grado di individuare i file in una cartella contenente una stringa di testo specifica utilizzando questo comando:

grep -lir 'string' ~/directory/*

Come posso spostare i file che appaiono nel risultato sopra in un'altra posizione?


Ecco qui. grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Alan Dong,

Risposte:


10

Come sempre, attenzione grep -r. -rnon è un'opzione standard e in alcune implementazioni come tutte le versioni GNU tranne quelle molto recenti grep, segue i collegamenti simbolici quando si discende dall'albero delle directory, che generalmente non è quello che si desidera e può avere implicazioni gravi se, ad esempio, esiste un collegamento simbolico a "/ "da qualche parte nella struttura di directory.

Nella filosofia Unix, si utilizza un comando per cercare file nelle directory e un altro per osservarne il contenuto.

Usando gli strumenti GNU, farei:

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

Ma anche in questo caso, fai attenzione alle condizioni di gara e ai possibili problemi di sicurezza se lo esegui come un utente su una directory scrivibile da un altro utente.


questo mi dà la ricerca dell'errore: `grep 'terminato dal segnale 13. Qualche idea di cosa non va?
Reena Parekh,

@ReenaParekh, sarebbe un SIGPIPE. Ciò accadrebbe solo se xargsuscisse prima di leggere fino alla fine del suo file arg che non dovrebbe accadere a meno che xargs non venga ucciso da solo o fallisca per qualsiasi motivo, nel qual caso mi aspetto che anche tu veda un errore.
Stéphane Chazelas,

15

Utilizzare xargsin concerto con mvla terza sintassi:mv [OPTION]... -t DIRECTORY SOURCE...

grep -lir 'string' ~/directory/* | xargs mv -t DEST

Fai attenzione ai file che contengono caratteri speciali (spazi, virgolette). In questo caso, potrebbe essere utile filtrare l'elenco con sed(aggiungendo virgolette attorno ai nomi dei file s/^/'/;s/$/'/), ma dovresti essere sicuro che queste citazioni non verranno visualizzate nei nomi dei file. GNU grepha l' opzione -Z/ --nullper terminare NUL i nomi dei file.

Un'alternativa alla terza sintassi per mvè l'utilizzo xargscon la stringa segnaposto ( -I).

Un'altra opzione è la sostituzione dei comandi - $( )o backtick ``(in bash) come menzionato nella risposta di ire_and_curses.


3
gnu grep supporta un flag -Z per separare i nomi dei file dal carattere zero byte, che se usato in congiunzione con il flag -0 per xargs, può aggirare i caratteri speciali che menzioni
iruvar

@ChandraRavoori grazie, ho aggiornato la risposta.
peterph,


2

Utilizzando solo le funzionalità specificate da POSIX e non fare ipotesi sui nomi dei file:

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

Appunti:

Hai detto "stringa" non "modello", quindi l' -Fopzione (ricerca stringa fissa) grepsembra appropriata.

Se la directory di destinazione si trova all'interno della directory di ricerca, è possibile che si verifichino condizioni di gara spiacevoli.

Specifiche POSIX per grep

Specifiche POSIX per find


Questa potrebbe essere la migliore soluzione su Macos / BSD
Ali

0

Usando GNU parallelo :

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dong per la sua risposta originale con xargs.


Sarebbe stato bello se tu avessi accreditato la risposta di @ lindong nei commenti di oltre un anno fa.
roaima,

0

-Supponi di avere la directory di destinazione come 'esterna' e devi spostare tutti i file XLS, puoi provare sotto il comando

sudo mv find /var/log/ -type f -name "*.xls"/ esterno /

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.