Copia tutti i file con una certa estensione da tutte le sottodirectory


112

In unix, voglio copiare tutti i file con una certa estensione (tutti i file Excel) da tutte le sottodirectory in un'altra directory. Ho il seguente comando:

cp --parents `find -name \*.xls*` /target_directory/

I problemi con questo comando sono:

  • Copia anche la struttura della directory e voglio solo i file (quindi tutti i file dovrebbero finire in / target_directory /)

  • Non copia i file con spazi nei nomi dei file (che sono piuttosto pochi)

Qualche soluzione per questi problemi?


Di cosa find... exec mv?
fedorqui 'SO stop harming'

Risposte:


174

--parents sta copiando la struttura della directory, quindi dovresti sbarazzartene.

Il modo in cui l'hai scritto, findviene eseguito e l'output viene messo sulla riga di comando in modo tale da cpnon poter distinguere tra gli spazi che separano i nomi dei file e gli spazi all'interno del nome del file. È meglio fare qualcosa di simile

$ find . -name \*.xls -exec cp {} newDir \;

in cui cpviene eseguito per ogni nome file che findtrova e passato correttamente il nome file. Ecco maggiori informazioni su questa tecnica.

Invece di tutto quanto sopra, puoi usare zsh e semplicemente digitare

$ cp **/*.xls target_directory

zsh può espandere i caratteri jolly per includere sottodirectory e rende questo genere di cose molto semplici.


2
Sì. 'bin it' significa buttarlo via. Ora modificato :-)
Brian Agnew

13
Bash4.0+ e ksh93supporta anche **. Per bash, usa shopt -s globstarper abilitarlo. Per ksh, è set -Go set -o globstar.
pynexj

2
@Daryl - ho compilato ulteriormente. Ma la risposta era già contrassegnata come "accettata", nota
Brian Agnew il

5
Quell'exec è tecnicamente meno efficiente del passaggio a xargs, che farà tutto con il minor numero possibile di chiamate cp: find . -name '*.xls' -print0 | xargs -0 cp -t destdir
Taywee

2
@BrianAgnew Oh, sono sicuro, è solo bello avere informazioni extra nei commenti per i googler ribelli.
Taywee

37

Da tutto quanto sopra, ho creato questa versione. Questa versione funziona anche per me nel terminale di ripristino del Mac.

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'

Cercherà nella directory corrente e ricorsivamente in tutte le sottodirectory per i file con estensione xsl. Li copierà tutti nella directory di destinazione.

I flag cp sono:

  • p - conserva gli attributi del file
  • r - ricorsivo
  • v - verbose (mostra cosa viene copiato)

1
Questo è lo stesso di quello che ho dovuto fare quando SSH è entrato in Bluehost.
Plummer

4
NON preserva le sottodirectory.
b005t3r

3
@ b005t3r che è di progettazione, non dovrebbe. Questo era l'intero intento della domanda dell'OP. Voleva che tutti i file delle sottodirectory fossero copiati in una directory senza sottodirectory
Madivad

2
C'è un modo per modificarlo per preservare le sottodirectory?
Matthew Dean,

8

Ho avuto un problema simile. L'ho risolto usando:

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"

L' '{}'e ";"esegue la copia su ogni file.


3

Ho dovuto farlo anche io. L'ho fatto tramite l'argomento --parents per cp:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;

1
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

puoi rimuovere --parents ma c'è il rischio di collisione se più file hanno lo stesso nome.

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.