Pindahkan semua file dengan ekstensi tertentu dari beberapa subdirektori ke satu direktori

43

Saya memiliki banyak file .zip di beberapa direktori:

Fol1/Fol2
Fol3
Fol4/Fol5

Bagaimana cara saya memindahkan semuanya ke folder basis umum?

InquilineKea
sumber
Apakah Anda ingin mempertahankan struktur direktori? Anda ingin memindahkan direktori, atau hanya file zip?
jordanm
Saya hanya ingin memindahkan file zip. Saya tidak terlalu peduli dengan direktori - mereka bisa dibiarkan sendiri atau dihapus.
InquilineKea

Jawaban:

55

Buka direktori tingkat atas pohon yang berisi file zip ( cd …), lalu jalankan

mv **/*.zip /path/to/single/target/directory

Ini berfungsi di luar kotak di zsh. Jika shell Anda adalah bash, Anda harus menjalankannya shopt -s globstarterlebih dahulu (Anda bisa dan harus meletakkan perintah ini di Anda ~/.bashrc). Jika shell Anda adalah ksh, Anda harus menjalankannya set -o globstarterlebih dahulu (letakkan di Anda ~/.kshrc).

Atau, gunakan find, yang bekerja di mana-mana tanpa persiapan khusus tetapi lebih rumit:

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

Jika Anda ingin menghapus direktori kosong setelahnya, di zsh:

rmdir **/*(/^Fod)

Dalam bash atau ksh:

rmdir **/*/

dan ulangi selama ada direktori kosong untuk dihapus. Atau, dalam cangkang apa pun

find . -depth -type d -empty -exec rmdir {} \;
Gilles 'SANGAT berhenti menjadi jahat'
sumber
findPerintah pertama di atas bekerja di bash, tetapi harus berubah ke find . -namedll untuk membuatnya berfungsi.
JeffThompson
1
@ Jeff .adalah implisit untuk menemukan GNU tetapi tidak untuk orang lain, saya telah menambahkannya secara eksplisit.
Gilles 'SANGAT berhenti menjadi jahat'
13

Jika Anda hanya ingin memindahkan .zipfile, Anda bisa melakukan sesuatu seperti

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;
Bernhard
sumber
3

Jika Anda menggunakan bash versi 4 atau lebih tinggi atau zsh, Anda juga dapat menggunakan globbing rekursif:

mv **/*.zip /path/to/move/zip/files/to

Ini HANYA akan memindahkan file dan bukan jalur relatifnya, sehingga benturan mungkin terjadi.

SuperMagic
sumber
apa yang Anda maksud dengan jalur relatif?
Kunok
2

Yang ini aman ketika memindahkan data dan bebas dari kesalahan yang mendukung sebagian besar semua distro tanpa memandang versi. Perintah ini akan memindai subdirektori dan kemudian memindahkan atau menyalin ke direktori tujuan baru Anda.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Jalankan perintah ini di direktori utama yang berisi sub-direktori dengan file yang ingin Anda pindahkan.
  • Di mana Anda dapat mengubah *.flacapa pun seperti *.zipdalam kasus Anda. Atau *.docsembarang ekstensi bekerja.
  • dan mvmerupakan perintah untuk memindahkan file, atau Anda dapat menggunakan cpuntuk menyalin data alih-alih memindahkan.
  • ./flac/adalah direktori tujuan tempat saya ingin memindahkan semua file FLAC. Anda juga dapat memberikannya path lengkap seperti/home/myid/flac/

Contoh lengkap. (dalam hal ini, ada banyak subdirektori dengan nama artis musik di /home/myid/Music/kemudian file FLAC adalah seluruh level subdirektori yang berbeda. Karena saya tidak memerlukan folder artis tetapi ingin memiliki semua file FLAC dalam satu direktori di/home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

Maka itu akan menampilkan semua file FLAC.

Seandex
sumber
apa yang ;harus dilakukan
Francesco Boi
@FrancescoBoi pastikan untuk menunggu sampai perintah bash di baris yang sama menyelesaikan tugasnya. dan kemudian pindah ke baris berikutnya dari perintah bash. Ini berguna untuk perintah yang berisi skrip seperti .pl atau python karena bash hanya akan menjalankannya dan kemudian melompat ke baris berikutnya, jadi agar aman, saya gunakan; setelah perintah yang membutuhkan waktu atau skrip, jika bash melewatkannya.
Seandex
0

Sebagai bash hack, Anda bisa menggunakan kekuatan tar:

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

Ini memiliki keuntungan karena tidak bergantung pada ekstensi file, karena ia menggunakan fileperintah untuk memilih file yang akan dipindahkan dan mempertahankan struktur direktori, tetapi tidak bekerja dengan jalur yang berisi spasi.

Final rmada di sana hanya untuk menghapus file asli (karena @InquilineKea memberi tahu bahwa dia tidak peduli dengan folder asli dalam komentar).

Tentu saja ini sangat cocok jika folder asal / dan target / berada pada disk yang berbeda. Kalau tidak, solusi lain yang diusulkan lebih efisien (bahkan jika mereka bergantung pada konvensi penamaan, alih-alih filekonten).

Giacomo Tesio
sumber
0

Dengan asumsi Anda memiliki versi pencarian dan mv GNU, yang berikut ini akan lebih efisien daripada jawaban berbasis penemuan yang ada:

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

Menggunakan a +di akhir find -exec berarti daftar file akan diteruskan ke perintah mv, daripada mengeksekusi satu perintah mv per file yang ditemukan. Namun, batasannya adalah Anda hanya dapat menempatkan '{}' di akhir perintah, yang mengharuskan penggunaan opsi mv --target-direktori, dan sejauh yang saya tahu itu adalah GNU-isme.

Evilsoup
sumber