Cara memindahkan semua file di dalam subfolder yang ada di sini

8

Saya memiliki 50 folder dengan beberapa subfolder juga, dengan total lebih dari 1000 file audio. Saya perlu menghapus semua subfolder dan meletakkan semua file di level sekarang. mv */* ./Sudah mencoba tetapi keluhan: daftar argumen terlalu panjang

Pedro Gonzalez
sumber

Jawaban:

7

Saya berasumsi bahwa ekstensi file audio Anda adalah .mp3

find <AudioFolderPath> -name '*.mp3' -exec mv -it <YourTargetFolder> {} +

Catatan:

  • Ganti .mp3dengan ekstensi file audio Anda

  • Ganti <AudioParentFolderPath>dengan folder induk yang berisi subfolder Anda.

  • Ganti <YourTargetFolder>dengan jalur folder tempat Anda harus meletakkan semua file.

  • Jika file derek dari subfolder yang berbeda memiliki nama yang sama, hanya satu yang akan dipindahkan.

sunting: Seperti yang dikatakan Costas : " -iSwitch ini membuat mvinteraktif, ia akan meminta sebelum menimpa file yang ada"

Muhammad
sumber
apakah '-t' memungkinkan Anda untuk menentukan tujuan terlebih dahulu? (karena saya tidak memiliki opsi ini pada "mv" saya di sini, saya hanya dapat berasumsi begitu Anda meletakkan folder tujuan terlebih dahulu dan kemudian daftar file untuk pindah ke sana ... tetapi jika tidak, ini akan mencoba untuk memasukkan semua di nama file terakhir, memberikan peringatan) tbisa untuk "target"?
Olivier Dulac
Ya seperti yang Anda katakan, -tizinkan untuk menentukan tujuan terlebih dahulu. dari mvhalaman manual: -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY
Muhammad
1
harap dicatat bahwa ini adalah opsi GNU mv, dan tidak tersedia di setiap unit (setidaknya di beberapa lingkungan produksi). Saya memberikan solusi yang lebih portabel, tetapi milik Anda berfungsi dengan baik untuk Linux
Olivier Dulac
ya @OlivierDulac, Anda benar, terima kasih atas catatan Anda.
Muhammad
4
find . -type f -mindepth 2 -exec mv -t ./ {} +

Perhatikan bahwa perintah itu akan menimpa file apa pun dengan nama yang sama. Anda dapat menggunakan ini untuk diminta sebelum menimpa:

find . -type f -mindepth 2 -exec mv -it ./ {} +

Penjelasan

  • -type f : hanya menemukan file biasa.
  • -mindepth 2 : temukan hanya file dalam subdirektori.
  • -exec mv -it ./ {}: -execsarana "jalankan perintah ini pada setiap file yang ditemukan". The {}akan diganti dengan nama file. The -iswitch membuat mvinteraktif, ia akan meminta sebelum Timpa file yang sudah ada dan -tmenetapkan target direktori untuk ./.
  • +: meletakkan file bersama-sama (dalam satu baris argumen) sehingga shell dapat beroperasi dengan perintah untuk memanggil waktu minimum perintah (bukan satu per satu tetapi satu ke beberapa).

Mengenai penghapusan folder kosong lebih lanjut, Anda dapat menggunakan resep yang sama:

find . -type d -empty -delete
Costas
sumber
1
-type fhanya memilih file biasa, tidak termasuk tautan simbolik, pipa bernama dan sejenisnya. Untuk memindahkan semua file selain dari direktori yang dapat Anda lakukan ! -type d.
jimmij
@ Jimmij Saya kira tidak ada yang menyimpan file audio sebagai pipa bernama atau sesuatu yang lain. Jika Anda khawatir tentang symlink, Anda dapat menggunakan -Lparameter
Costas
1
-iadalah standar, -thanya untuk GNU (tidak ada hubungannya dengan Linux yang hanya sebuah kernel yang ditemukan di beberapa sistem GNU dan non-GNU)
Stéphane Chazelas
Saya setuju dengan @ StéphaneChazelas: -ttidak ada pada beberapa sistem (seperti AIX yang tidak terlalu kuno)
Olivier Dulac
@OlivierDulac Hampir tidak mungkin menemukan keputusan untuk memuaskan semua orang sehingga varian yang berbeda dipersilakan. Tidak ada yang melarang Anda untuk mengubah string kefind . -type f -mindepth 2 -exec mv {} ./ \;
Costas
2

Ya, itu batas ukuran kumulatif argumen dan lingkungan yang diteruskan ke execve()panggilan sistem saat menjalankan perintah eksternal.

Dengan zsh, Anda dapat menggunakan builtin mvsebagai gantinya:

zmodload -F zsh/files +b:zf_mv
zf_mv ./*/* .

Atau gunakan zargsuntuk memecah daftar menjadi potongan yang bisa diatur:

autoload zargs
zargs -Ifiles ./*/* -- mv files .

Dengan ksh93:

command -x mv ./*/* .

Dengan GNU xargsdan dengan GNU mvdengan shell di mana printfbuiltin (kebanyakan, mkshmenjadi pengecualian):

printf '%s\0' ./*/* | xargs -r0 mv -t .
Stéphane Chazelas
sumber
Harap diingat bahwa OP hanya ingin memindahkan file, bukan direktori, jadi Anda harus mengurusnya. Dalam zshhal ini Anda dapat menaruh beberapa kualifikasi gumpal , misalnya (.)atau (^/)setelah terakhir *.
jimmij
0

Solusi yang cukup portabel adalah:

temukan semua file di setiap subfolder, dan pindahkan dalam direktori saat ini

find ./*/ -type f -print | xargs mv -i "{}" ./

Anda dapat menambahkan | egrep "\.au$|\.mp3$|\.ac3$"di antara untuk juga memastikan file yang Anda temukan adalah file dengan ekstensi audio (tambahkan ekstensi sebanyak yang diperlukan untuk mencakup semua jenis, saya hanya menyediakan 3 yang umum)

Olivier Dulac
sumber
Dalam kasus Anda, tidak perlu menelepon findsama sekali. Cukup echoatauprintf
Costas
@ Costas: OP menyebutkan ada begitu banyak file yang "*" tidak dapat diperluas ... Di sini saya hanya perlu memperluas 50 nama folder, dan sisanya ditangani oleh xargs
Olivier Dulac
Tapi findjangan menyelesaikan masalah tetapi xargslakukan.
Costas