Ini mungkin sangat sederhana, tetapi saya tidak bisa mengetahuinya. Saya memiliki struktur direktori seperti ini (dir2 ada di dalam dir1):
/dir1
/dir2
|
--- file1
|
--- file2
Apa cara terbaik untuk 'meratakan' struktur direktur ini sedemikian rupa untuk mendapatkan file1 dan file2 di dir1 bukan dir2.
Jawaban:
Anda dapat melakukan ini dengan GNU
find
dan GNUmv
:Pada dasarnya, cara yang berfungsi jika
find
melewati seluruh pohon direktori dan untuk setiap file (-type f
) yang tidak ada di direktori tingkat atas (-mindepth 2
), ia menjalankan amv
untuk memindahkannya ke direktori yang Anda inginkan (-exec mv … +
). The-t
argumen untukmv
memungkinkan Anda menentukan direktori tujuan pertama, yang diperlukan karena+
bentuk-exec
menempatkan semua lokasi sumber di akhir perintah. The-i
merekmv
bertanya sebelum Timpa duplikat apapun; Anda dapat menggantikan-f
menimpa mereka tanpa meminta (atau-n
untuk tidak meminta atau menimpa).Seperti yang ditunjukkan Stephane Chazelas, hal di atas hanya berfungsi dengan alat GNU (yang merupakan standar pada Linux, tetapi tidak pada kebanyakan sistem lainnya). Berikut ini agak lambat (karena memanggil
mv
beberapa kali) tetapi jauh lebih universal:sumber
-exec +
sehingga tidak menjalankan sejumlah besar prosesmv
mv
membutuhkan tujuan sebagai argumen terakhir, tetapi + akan memiliki sumber sebagai argumen terakhir. Cari bahkan tidak akan menerima sintaks Anda mengubahnya menjadi (find: missing argument to `-exec'
)mv
memiliki-t
kita bisa menggunakan, jadi saya akan mengubahnya ke itu.find
mencetak file tersembunyi (titik) secara default. Kedalamannya relatif terhadap direktori yang Anda lewati untuk menemukan.find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'
jikaDalam zsh:
**/
melintasi subdirektori secara rekursif. The kualifikasi gumpal.
cocok file biasa saja, danD
memastikan bahwa file dot disertakan (secara default, file yang namanya dimulai dengan.
dikecualikan dari wildcard cocok). Untuk membersihkan direktori yang kosong sekarang, jalankanrmdir dir1/**/*(/Dod)
-/
batasi ke direktori, danod
pesan kedalaman pertandingan terlebih dahulu untuk dihilangkandir1/dir2/dir3
sebelumnyadir1/dir2
.Jika panjang total nama file sangat besar, Anda dapat mengalami batasan pada panjang baris perintah. Zsh memiliki bawaan untuk
mv
danrmdir
yang tidak terpengaruh oleh batasan ini: jalankanzmodload zsh/files
untuk mengaktifkannya.Dengan hanya alat POSIX:
atau (lebih cepat karena tidak harus menjalankan proses terpisah untuk setiap file)
sumber
Coba lakukan ini:
atau untuk setiap file yang cocok
file[0-9]*
dengan subdir:Lihat http://mywiki.wooledge.org/glob
sumber
{}
dalam masalah saya yang sebenarnya.Saya menulis dua fungsi yang dapat Anda gunakan bersama yang melakukan hal itu, Anda dapat membatasi level direktori dengan menambahkan
-maxdepth $VAL
parameter.sumber
Memperluas jawaban populer untuk pertanyaan ini, karena saya memiliki kasus penggunaan untuk meratakan direktori yang berisi file dengan nama yang sama.
Dalam hal ini, opsi
-i
(--interactive
) yang diteruskan kemv
tidak akan menghasilkan hasil yang diinginkan untuk meratakan struktur direktori dan menangani konflik nama. Jadi itu hanya diganti dengan--backup=t
(setara dengan--backup=numbered
). Dokumentasi lebih lanjut tentang opsi-b
(--backup
) tersedia di https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options .Yang menghasilkan:
Yang menghasilkan:
sumber
tar dan zip keduanya memiliki kemampuan untuk menggabungkan dan kemudian menghapus struktur direktori, jadi saya dapat dengan cepat meratakan direktori bersarang dengan
tar -cvf all.tar *
diikuti dengan memindahkan all.tar ke lokasi baru
tar -xvf all.tar --strip=4
sumber