Salin semua file dengan ekstensi tertentu dari semua subdirektori

112

Di bawah unix, saya ingin menyalin semua file dengan ekstensi tertentu (semua file excel) dari semua subdirektori ke direktori lain. Saya memiliki perintah berikut:

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

Masalah dengan perintah ini adalah:

  • Ini menyalin struktur direktori juga, dan saya hanya ingin file (jadi semua file harus berakhir di / target_directory /)

  • Itu tidak menyalin file dengan spasi di nama file (yang cukup banyak)

Ada solusi untuk masalah ini?

Abdel
sumber
Tentang apa find... exec mv?
fedorqui 'SO berhenti melukai'

Jawaban:

174

--parents sedang menyalin struktur direktori, jadi Anda harus menyingkirkannya.

Cara Anda menulis ini, findeksekusi, dan output diletakkan ke baris perintah sedemikian rupa sehingga cptidak dapat membedakan antara spasi yang memisahkan nama file, dan spasi di dalam nama file. Lebih baik melakukan sesuatu seperti

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

di mana cpdijalankan untuk setiap nama file yang findmenemukan, dan meneruskan nama file dengan benar. Berikut info lebih lanjut tentang teknik ini.

Alih-alih semua hal di atas, Anda bisa menggunakan zsh dan cukup ketik

$ cp **/*.xls target_directory

zsh dapat memperluas wildcard untuk menyertakan subdirektori dan membuat hal semacam ini sangat mudah.

Brian Agnew
sumber
2
Iya. 'bin it' artinya membuangnya. Sekarang diubah :-)
Brian Agnew
13
Bash4.0+ dan ksh93juga mendukung **. Untuk bash, gunakan shopt -s globstaruntuk mengaktifkannya. Untuk ksh, itu set -Gatau set -o globstar.
pynexj
2
@Daryl - Saya sudah mengisi lebih lanjut. Tapi jawabannya sudah ditandai sebagai 'diterima', catatan
Brian Agnew
5
Eksekutif itu secara teknis kurang efisien daripada meneruskan ke xargs, yang akan melakukan semuanya dalam panggilan cp sesedikit mungkin: find . -name '*.xls' -print0 | xargs -0 cp -t destdir
Taywee
2
@BrianAgnew Oh, saya yakin, senang memiliki informasi tambahan di komentar untuk googler bandel.
Taywee
37

Dari semua hal di atas, saya datang dengan versi ini. Versi ini juga berfungsi untuk saya di terminal pemulihan mac.

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

Ini akan mencari di direktori saat ini dan secara rekursif di semua sub direktori untuk file dengan ekstensi xsl. Ini akan menyalin semuanya ke direktori target.

cp flags adalah:

  • p - pertahankan atribut file
  • r - rekursif
  • v - verbose (menunjukkan apa yang sedang disalin)
guya
sumber
1
Ini sama seperti yang harus saya lakukan ketika SSH masuk ke Bluehost.
Plummer
4
Ini TIDAK melindungi subdirektori.
b005t3r
3
@ b005t3r yang dengan desain, tidak seharusnya. Itulah maksud dari pertanyaan OP. Dia ingin semua file dari subdirektori disalin ke satu direktori tanpa subdirektori
Madivad
2
Apakah ada cara untuk memodifikasi ini untuk mempertahankan sub-direktori?
Matthew Dean
8

Saya memiliki masalah serupa. Saya menyelesaikannya menggunakan:

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

The '{}'dan ";"mengeksekusi copy pada setiap file.

stingMantis
sumber
3

Saya juga harus melakukan ini sendiri. Saya melakukannya melalui argumen --parents untuk cp:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;
Orang itu
sumber
1
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

Anda dapat menghapus --parents tetapi ada risiko bentrok jika beberapa file memiliki nama yang sama.

Truk
sumber