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?
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?
Risposte:
Come sempre, attenzione grep -r
. -r
non è 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.
xargs
uscisse 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.
Utilizzare xargs
in concerto con mv
la 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 grep
ha l' opzione -Z
/ --null
per terminare NUL i nomi dei file.
Un'alternativa alla terza sintassi per mv
è l'utilizzo xargs
con la stringa segnaposto ( -I
).
Un'altra opzione è la sostituzione dei comandi - $( )
o backtick ``
(in bash) come menzionato nella risposta di ire_and_curses.
Se i nomi dei tuoi file non contengono caratteri speciali (spazi bianchi o \[*?
), usa la sostituzione dei comandi :
mv `grep -lir 'string' ~/directory/*` destination/
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' -F
opzione (ricerca stringa fissa) grep
sembra appropriata.
Se la directory di destinazione si trova all'interno della directory di ricerca, è possibile che si verifichino condizioni di gara spiacevoli.
Usando GNU parallelo :
grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'
ht / @ lin-dong per la sua risposta originale con xargs.
-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 /
grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name