Linux: copia tutti i file corrispondenti al modello da dir e sottodir in una singola dir


31

Se volessi copiare tutti i *.sofile da srca dstfarei:

cp src/*.so dst

Tuttavia, voglio copiare tutti *.soi file da src e IT di sottodirectory in dst. Qualche indizio?

Risposte:


36

Provare:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

17
findpuò fare pattern matching ed eseguire comandi. Non è necessario find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
— convogliare il

1
Sì, può, tuttavia, spesso è più facile leggere una pipeline, anche le capacità di corrispondenza dei grepmodelli superano di gran lunga i semplici modelli di shell utilizzati nel -nameparametro find. xargsè anche molto più potente del -execparametro to find.
— Mike Insch,

2
La soluzione di @jaquer è molto migliore perché su MacOSX l'utilità xargs non ha l'opzione -i. Ma la sua soluzione funziona come un fascino.
— bialix,

Stavo lottando con un messaggio di errore sull'argomento -i di xargs fino a quando non ho letto il commento di @bialix sulla soluzione di Jaquer, che ha funzionato perfettamente sul mio Mac. Grazie
— svannoy,

Questo creerà le sottodirectory secondo necessità?
— Lennart Rolland,

15

Se stai usando Bash, puoi attivare l' globstar opzione shell per abbinare ricorsivamente file e directory:

shopt -s globstar
cp src/**/*.so dst

Se devi trovare file i cui nomi iniziano con ., e / o file dentro e sotto le directory i cui nomi iniziano con ., imposta anche l' dotglobopzione (es. Con shopt -s dotglob). Puoi impostarli entrambi in un solo comando:

shopt -s globstar dotglob

Non copia i file nelle sottodirectory che iniziano con a. nel loro nome
— rboy

8

Ho provato il comando suggerito da Mike:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

ma alla fine ha scaricato tutti i file nella directory dstcon i relativi percorsi persi.

Per mantenere i percorsi relativi, il comando deve essere modificato in questo modo:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}

7
+1. Tuttavia, ciò presuppone che esistano le directory corrispondenti ai percorsi di origine relativi dst. Nel caso non fosse così, utilizzare cp --parents. Inoltre, assicurati di citare i nomi dei file. Pertanto: ... | xargs -i cp --parents "{}" dst(si noti che l'ultimo argomento a cpè ora "solo" la directory di destinazione). Il comando può essere reso ancora più breve (e probabilmente più veloce) con la -tbandiera: ... | xargs cp --parents -t dst.
— Stephan202,

1
@ Stephan202 ho dovuto usare... | xargs cp {} --parents -t dst.
— warvariuc l'

per quelli su un Mac, --parentsnon è disponibile. Ho usato dittoal suo posto: stackoverflow.com/questions/11246070/cp-parents-option-on-mac
— Bryan Young

3

Un altro modo per farlo è così:

find src/ -type f -name "*.so" -exec cp {} dst/ \;

E questo dovrebbe ridurre il numero di cpprocessi: ... -exec cp -t dst/ {} +.
— Kamil Maciorowski,

Ehi Kamil! Grazie per il commento! Potete per favore spiegarmi come la vostra soluzione rende le cose più veloci! Sempre disposto a saperne di più :)
— Kyriakos

Quando si termina -execcon ;, {}è sostituito da un percorso alla volta. Ne ottieni uno separato cpper ogni file. Con la +sintassi findsostituisce {}con risultati multipli (fino a un limite definito dal sistema della lunghezza della riga di comando; restrizione: {}deve essere l'ultima cosa prima +, quindi cp -t). Creare e terminare un processo è una cosa relativamente costosa. Per questo motivo è consigliabile utilizzarlo +ogni volta che si prevedono molti risultati. In questo caso la copia di molti file potrebbe richiedere comunque molto tempo, quindi la differenza potrebbe passare inosservata; tuttavia è una buona pratica.
— Kamil Maciorowski il

1

Il grep può essere sostituito usando find's -name :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
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.