Innanzitutto, capisci che la pipe "|" collega i comandi reindirizzando l'output del primo nel secondo come argomento. I tuoi due codici shell convogliano entrambi l'output del comando find in altri comandi (grep e xargs). Diamo un'occhiata a quei comandi uno dopo l'altro:
Primo comando:trova
find è un programma per "cercare file in una gerarchia di directory" (questa è la spiegazione dalla pagina man di find). La sintassi è (in questo caso)
find <search directory> <search pattern> <action>
In entrambi i casi la directory di ricerca è . (questa è la directory corrente). Nota che non cerca solo nella directory corrente ma anche in tutte le sue sottodirectory (la gerarchia delle directory).
Il modello di ricerca accetta le opzioni -name (il che significa che cerca i file il cui nome corrisponde al modello dato come argomento a questa opzione) o -iname (uguale a name ma senza distinzione tra maiuscole e minuscole) tra le altre.
Il modello di azione può essere -print0 (stampa il nome esatto del file inclusa la sua posizione nella directory di ricerca data, cioè il percorso relativo o assoluto del file) o -exec (esegue il comando dato sui file, il comando è quello di essere terminato con ";" e ogni istanza di "{}" è sostituita dal nome del file).
Ovvero, il primo codice shell (prima parte, a sinistra della pipe)
find . -iname \*.jpg -print0
cerca tutti i file che terminano con ".jpg" nella gerarchia di directory corrente e stampa i loro percorsi e nomi. La seconda (prima parte)
find . -name '*' -exec file {} \;
trova tutti i file nella gerarchia di directory corrente ed esegue
file <filename>
su di essi. File è un altro comando che determina e stampa il tipo di file (dai un'occhiata alla pagina man per i dettagli, man file).
Secondo comando:xargs
xargs è un comando che "costruisce ed esegue righe di comando dall'input standard" (man xargs), ovvero dall'output find che viene reindirizzato in xargs. Il comando che crea ed esegue è in questo caso
cp -v {} /home/joachim/neu2"
L'opzione -I{} definisce la stringa di sostituzione, ovvero ogni istanza di {} nel comando deve essere sostituita dall'input che riceve dal file (ovvero, i nomi dei file). L'opzione -0 definisce che gli elementi di input non sono terminati (separati) da spazi bianchi o nuove righe ma solo da un carattere nullo. Questo sembra essere necessario quando si utilizza e il modo standard per gestire l'output di find come input xargs.
Il comando che viene compilato ed eseguito è ovviamente il comando copy con l'opzione -v (verbose) e copia ciascuno dei nomi di file che ottiene da find nella directory.
Terzo comando:grep
grep filtra il suo input fornendo solo quelle righe o stringhe che corrispondono a un particolare modello di output. L'opzione -o dice a grep di stampare solo la stringa corrispondente, non l'intera riga (vedi man grep), -P gli dice di interpretare il seguente pattern come un pattern regexp perl. In perl regex, ^ è l'inizio della riga, .+ è qualsiasi stringa arbitraria, questo arbitrario dovrebbe quindi essere seguito da due punti, uno spazio, un numero di caratteri alfanumerici (in perl regex indicato con \w+) uno spazio e la stringa "Immagine". Essenzialmente questo comando grep filtra l'output del file per emettere solo i nomi di file che sono file di immagine. (Per esempio leggi le espressioni regolari perl qui:http://www.comp.leeds.ac.uk/Perl/matching.html )
Il comando che volevi davvero
Ora quello che vuoi fare è (1) prendere l'output del secondo comando shell (che elenca i file di immagine), (2) portarlo nella forma appropriata e (3) inserirlo nel comando xargs dal primo comando shell line (che quindi compila ed esegue il comando di copia desiderato). Quindi questa volta abbiamo un comando shell a tre (in realtà quattro) stadi con due pipe. Non è un problema. Abbiamo già le fasi (1) e (3) (sebbene nella fase (3) dobbiamo tralasciare l'opzione -0 perché l'input non è più find output; ne abbiamo bisogno per trattare le nuove righe come separatori di elementi).
Manca ancora lo stadio (2). Suggerisco di utilizzare il comando cut per questo. cut modifica le stringhe py suddividendole in diversi campi (separati da un carattere delimitatore nella stringa originale) che possono quindi essere riorganizzati. Sceglierò ":" come carattere delimitatore (questo termina il nome del file nell'output di grep, opzione -d':') e gli dirò di darci solo il primo campo (opzione -f1, essentialls:print only the filename, not la parte che segue il ":"), cioè lo stadio (2) sarebbe allora
cut -d':' -f1
E l'intero comando che volevi sarà quindi:
find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I{} cp -v {} /home/joachim/neu2
Nota che puoi trovare tutte le pagine man per esempio qui:http://www.linuxmanpages.com