2014-06-16 4 views
7

sistema operativo Linux Minttrovare e copiare tutte le immagini nella directory utilizzando menta linux terminale, cercando di capire la sintassi

Come dice il titolo, infine, mi piacerebbe trovare e copiare tutte le immagini in una directory.

ho trovato:

trovare alls file JPG (o JPG) nella directory e copiarli nella cartella/home/Joachim/neu2:

find . -iname \*.jpg -print0 | xargs -I{} -0 cp -v {} /home/joachim/neu2 

e

find tutti i file di immagini in direcotry:

find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' 

Il mio problema è prima di tutto, non capisco davvero la sintassi. Qualcuno potrebbe spiegare il codice?

E in secondo qualcuno può collegare i due codici per la generazione di un codice che fa quello che voglio;)

Saluti e grazie in anticipo!

E ancora una spiegazione del codice sarebbe molto utile.

risposta

15

Innanzitutto, capire che il tubo "|" links comanda l'invio dell'output del primo al secondo come argomento. I due codici shell eseguono entrambi l'output pipe del comando find in altri comandi (grep e xargs). Diamo un'occhiata a questi comandi uno dopo l'altro:

primo comando: trovare

ritrovamento è un programma per "cercare i file in una gerarchia di directory" (vale a dire la spiegazione da 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). Si noti che non ricerca solo la directory corrente ma anche tutte le sue sottodirectory (la gerarchia di directory).

Il modello di ricerca accetta opzioni -name (nel senso che cerca i file il cui nome corrisponde al modello fornito come argomento a questa opzione) o -iname (come il nome ma distingue tra maiuscole e minuscole) tra gli altri.

Il modello di azione può essere -print0 (stampare il nome file esatto inclusa la sua posizione nella directory di ricerca specificata, ovvero il percorso relativo o assoluto del file) o -exec (eseguire il comando dato sul file o sui file, il comando deve essere terminato con ";" e ogni istanza di "{}" viene sostituita dal nome file).

Cioè, il primo codice shell (prima parte, a sinistra del tubo)

find . -iname \*.jpg -print0 

ricerche tutti i file con estensione ".jpg" nella gerarchia di directory corrente e stampa i loro percorsi e nomi.Il secondo (prima parte)

find . -name '*' -exec file {} \; 

trova tutti i file nella gerarchia di directory corrente ed esegue

file <filename> 

su di loro. Il file è un altro comando che determina e stampa il tipo di file (dai un'occhiata alla pagina man per i dettagli, file man).

secondo comando: xargs

xargs è un comando che "costruisce e righe di comando exectues dall'input standard" (uomo xargs), ossia dall'uscita scoperta che viene incanalato nella xargs. Il comando che costruisce ed esegue in questo caso

cp -v {} /home/joachim/neu2" 

opzione -I {} definisce la stringa di sostituzione, cioè ogni istanza di {} nel comando deve essere sostituita dall'ingresso ottiene da file (che è, i nomi dei file). L'opzione -0 definisce che gli elementi di input non sono terminati (separati) da spazi vuoti o newline ma solo da un carattere nullo. Questo sembra essere necessario quando si utilizza e il modo standard per gestire l'output di ricerca come input xargs.

Il comando che viene creato ed eseguito è, ovviamente, il comando di copia con l'opzione -v (verbose) e copia ciascuno dei nomi di file che trova da find nella directory.

Terzo comando: grep

grep filtra dando il suo contributo solo quelle linee o stringhe che corrispondono a un particolare modello di uscita. L'opzione -o dice a grep di stampare solo la stringa corrispondente, non l'intera riga (vedi man grep), -P dice di interpretare il seguente modello come un modello di regexp perl. In perge regex,^è l'inizio della riga,. + È una qualsiasi stringa arbitraria, questo arbitrario dovrebbe quindi essere seguito da due punti, uno spazio, un numero di caratteri alfanumerici (in perl regex denotato \ w +) uno spazio e la stringa "Immagine". Essenzialmente questo comando grep filtra l'output del file per generare solo i nomi file che sono file immagine. (Leggi perl regex di, per esempio qui: http://www.comp.leeds.ac.uk/Perl/matching.html)

il comando che in realtà voleva

Ora ciò che si vuole fare è (1) prendere l'uscita del comando secondo guscio (che elenca i file di immagine), (2) portalo nella forma appropriata e (3) collegalo al comando xargs dalla prima riga di comando della shell (che poi costruisce ed esegue il comando di copia che volevi). Quindi questa volta abbiamo un comando di shell di tre (in realtà quattro) stage con due pipe. Non è un problema. Abbiamo già stage (1) e (3) (sebbene nello stage (3) abbiamo bisogno di lasciare fuori l'opzione -0 perché l'input non è più in uscita, ci serve per trattare le newline come separatori di elementi).

Stage (2) è ancora mancante. Suggerisco di usare il comando di taglio per questo. taglia le stringhe e le divide in campi diversi (separati da un carattere delimitatore nella stringa originale) che può quindi essere riorganizzato. Sceglierò ":" come carattere delimitatore (questo termina il nome file nell'output di grep, opzione -d ':') e ditelo per darci solo il primo campo (opzione -f1, essentialls: stampa solo il nomefile, non la parte che viene dopo ":"), esstadio (2) sarebbe allora

cut -d':' -f1 

E l'intero comando si voleva sarà quindi:

find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I{} cp -v {} /home/joachim/neu2 

noti che è possibile trovare tutte le pagine man per esempio qui: http://www.linuxmanpages.com

+0

Grazie mille !!! La tua risposta contiene così tante informazioni che mi aiutano davvero a capire meglio l'intera faccenda. – newandlost

+0

Ed è pazzesco quanto si deve sapere per capire i comandi. – newandlost

+0

Quando dici " " ... o -exec (esegui il comando dato sul/i file/i, il comando deve essere terminato con ";" ... " significa in realtà \; o perché è c'è un \? – newandlost

0

I capito un comando usando solo awk che fa anche il lavoro:

find . -name '*' -exec file {} \; | 
awk '{ 
    if ($3=="image"){ 
     print substr($1, 0, length($1)-1); 
     system("cp " substr($1, 0, length($1)-1) " /home/joachim/neu2") 
    } 
}' 

il substr ($ 1, 0, len gth ($ 1) -1) è necessario perché nel file della prima colonna restituisce il nome;

0

La risposta sopra è veramente buona. ma potrebbe richiedere più tempo se si tratta di una directory enorme. qui è una versione più corta di esso, se si conosce già l'estensione del file

find . -name \*.jpg | cut -d':' -f1 | xargs -I{} cp --parents -v {} ~/testimage/ 
Problemi correlati