Saya baru saja kehilangan sebagian kecil dari koleksi audio saya, karena kesalahan bodoh yang saya buat. :-(
SANGAT SAYA punya cadangan yang cukup baru, tapi itu masih menjengkelkan. Terlepas dari Anda benar-benar, penyebab lain melakukan kejahatan itu mv
, yang akan ditampilkan sebagai berikut:
File audio memiliki skema tertentu:
ARTIST - Some Title YY.mp3
di mana YY
spesifikasi tahun 2 digit.
mkdir 90<invisible control character>
(Sampai saat ini, saya tidak tahu bahwa saya benar-benar mengetik sepertiga karakter berlebih yang tidak terlihat ...!)
Daripada memiliki semuanya dalam satu direktori, saya ingin memiliki semua musik tahun 1990-an dalam satu direktori. Jadi saya mengetik:
find . -name '* 9?.mp3' -exec mv {} 90 \;
Tidak terlalu sulit untuk mengetahui apa yang terjadi, eh? : ->
Hasil (bencana) adalah direktori kosong perawan yang disebut '90 something '(dengan sesuatu menjadi karakter kontrol "tidak terlihat") dan satu file tunggal yang disebut' 90 ', ditimpa sebanyak n kali.
SEMUA FILE TELAH PERGI. : - (((jelas))
Wish mv
akan sudah memeriksa dalam waktu apakah tanda tangan "file" tujuan (ingat pada * NIX: Everything Is A File ) dimulai dengan d------
(misalnya drwxr-xr-x
). Dan, tentu saja, apakah tujuan itu ada atau tidak . Ada varian dari skenario tersebut, ketika Anda hanya lupa untuk mkdir
direktori yang pertama. (tapi tentu saja, Anda berasumsi bahwa itu ada di sana ...)
Bahkan kami OS hewan peliharaan-kebencian dimulai dengan modal W APAKAH DO INI. Anda bahkan diminta untuk menentukan jenis tujuan (file? Direktori?) Jika Anda memintanya.
Oleh karena itu, saya bertanya-tanya apakah kita * NIXers masih harus menulis sendiri " mv
scriptlet" hanya untuk menghindari kejutan yang tidak diinginkan semacam ini.
.mp3
harus ada di sana dengan nama90
, itu bisa menjadi salah satu yang Anda tidak punya cadangan.mv
bukan masalah di sini, secara teknis, tidak tahu bahwa Anda memindahkan serangkaian file. Anda menjalankanmv
satu kali untuk setiap file. Begitulah carafind -exec ;
kerjanya. Jika Anda menggunakanfind -exec +
(seperti dalam beberapa komentar)mv
akan menjerit begitu mendapat lebih dari satu argumen.mv
untuk setiap file tunggal mungkin tampak sedikit kurang dipikirkan pada awalnya, itu akan (seperti yang saya katakan sebelumnya) menjadi satu-satunya solusi waras setelah file sumber tersebar di berbagai subdirektori. Bahwa dalam case-test saya, file-file source semuanya dalam satu direktori tidak berarti itu adalah case test saya yang sebenarnya . Ini sebenarnya hanya penyederhanaan, karena saya dapat dengan mudah menjelaskannya sendiri nanti. Plus, itu membuat pertanyaan kurang memakan waktu untuk membaca karena panjangnya berkurang. :)mv
mengharuskan destinasi itu ada?mv oldfile newfile
adalah cara untuk mengubah nama file, dan konyol untuk berharapnewfile
sudah ada dan menjadi direktori.Jawaban:
Anda dapat menambahkan
/
ke tujuan jika Anda ingin memindahkan file ke direktori. Jika direktori tidak ada Anda akan menerima kesalahan:Jika ada direktori, itu memindahkan file ke direktori itu.
sumber
GNU coreutils
mv
sudah memiliki opsi yang menyatakan bahwa Anda ingin pindah ke direktori:-t
/--target-directory
. Jika argumen untuk opsi itu tidak ada,mv
akan mengeluh alih-alih memindahkan semua file Anda ke nama file yang sama.Saya akan menulis penggerak Anda sebagai berikut:
Perhatikan penggunaan
+
alih - alih\;
, globbing sebanyak nama file sebanyak mungkin, menghasilkan eksekusi yang lebih cepat.sumber
find . -name '* 9?.mp3' -exec sh -c 'exec mv "$@" 90/' sh {} +
Selain itu, jika Anda umumnya berencana untuk menghindari overwrite yang tidak disengaja di masa mendatang, ada
-i
opsi untukmv
. Saya pribadi tidak bisa memikirkan kelemahannya jika AndaJika Anda perlu menimpa sesuatu, cukup berikan
-f
opsi.Alias hanya berlaku jika Anda mengetik perintah langsung ke shell interaktif, bukan untuk kasus seperti doa oleh
find
. Anda bisa berlaridan kemudian Anda akan diminta jika
mv
mencoba menimpa file yang ada.sumber
mv
. "Trik" yang kurang dikenal ini akan menyebabkan perintah dengan backslash didahulukan untuk mengabaikan definisi alias apa pun .find ... -exec mv ...
, maka Anda harus membuat~/bin/mv
(atau direktori lain yang sesuai) dan melakukannya/bin/mv -i "$@"
- karenafind ... -exec
tidak melihat alias.env mv
. Kurang mengetik. :) Karena tata letak keyboard lokal saya memerlukan tombol SHIFT untuk ditekan untuk garis miring, saya akan selalu menyukai versi "tanpa garis miring" (jika ada).mv
di lokasi di awal$PATH
akan menjadi solusi yang lebih bersih. Di sisi lain saya terutama terjadi secaramv
ceroboh di shell interaktif (karena itu terjadi cepat). Saat saya menyusun sesuatu yang lebih kompleks, sepertifind
ataufor
loop, atau bahkan skrip shell, saya cenderung melakukan beberapa run kering (menggunakanecho
) untuk memastikan saya tidak merusak sesuatu. Dalam kasus-kasus itu saya tidak perlu berpegangan tanganmv
, karena saya sudah memikirkannya.Selain jawaban yang sangat baik di atas, saya ingin menjelaskan mengapa Anda tidak mendapatkan pertanyaan tentang apakah akan memindahkan file atau tidak.
Jika Anda memindahkan satu file ke nama baru, dan nama itu bukan direktori,
mv
akan mengubah nama file Anda ke nama baru.Masalahnya di sini adalah bahwa Anda menggunakan
find
untuk mengeksekusimv
sekali per file , bukan sekali untuk semua file .Jika, sebaliknya, Anda sudah selesai
mv *90.mp3 90
, makamv
akan gagal dengan pesan kesalahan bahwa "file target bukan direktori".Saran lain adalah menggunakan penyelesaian tab saat mengetik lintasan target. Ini akan menunjukkan kepada Anda apakah targetnya adalah direktori dengan menambahkan
/
ke nama target. Anda juga dapat menggunakanmv -i
untuk ditanya apakah Anda ingin menimpa file yang ada.sumber
mv *90.mp3 90
, maka mv akan gagal dengan pesan kesalahan bahwa "file target bukan direktori". Hah, ya, kenapa begitu rumit ya? Saya menggunakan kalimat Anda dan saya akan senang. Namun hanya dalam kasus sepele ini. :) Karena ini adalah cara normal saya mengajukan pertanyaan saya: Saya akan mempersempitnya demi kesederhanaan. Tidak ada yang keberatanfind
sejauh ini mengingat bahwa file 90-an mungkin juga tersebar di berbagai subdirektori yang ingin saya "tangkap" juga. Jika dan hanya jika mereka selalu ada dalam satu direktori sumber,mv
baris Anda berlaku.mv
berperilaku, bukan sebagai kritik terhadap pilihan alat Anda.find
danmv
, misalnyafind /music -type d -exec mv {}/*90.mp3 targetdir\;
- tetapi sekarang saya merasa agak seperti terlalu rumit, dan hanya menggunakan-i
atau-t
lebih efisienfind . -type d -exec mv {}/*9?.mp3 target \;
contoh Anda berhasil, masih akan ada risiko bahwamv
perintah akan terlihat sepertimv file target
untuk setiap direktori yang hanya berisi satu*9?.mp3
file; jadi semua file tersebut (kecuali yang terakhir) akan hilang.*.mp3
file di pohon direktori, Anda bisashopt -s globstar
dan kemudian menjalankan perintah Anda**/*.mp3
-**
akan bertindak seperti afind
.Sebagai strategi tujuan umum alternatif, saya ingin menyarankan untuk mengubah operasi semacam ini menjadi skrip sementara. Saya lebih suka melihat hasil
find
dan mengubahnya menjadimv
perintah dengan tangan, memastikan bahwa saya mengerti apa yang saya lakukan sebelum saya jalankan. misalnya.Sekarang saya dapat melihat daftar nama file dan menulis ulang isi file sebagai perintah shell.
ggVGJ
Imv
[esc]
Asomedir/
[esc]
source tmp
di baris perintah.Ini adalah strategi konservatif, tetapi saya sudah terlalu sering digigit oleh salah ketik
-exec
ataused
perintah yang perintah, atau ekspansi shell yang disalahpahami, dan saya lebih suka mengambil pendekatan yang lambat dan konsisten.Dengan kata lain: Saya terlalu pengecut untuk digunakan
-exec
.sumber
:%s/.*/"&"/
langkah - karena, dalam hal ini, Anda tahu bahwa setiap nama file mengandung setidaknya satu ruang.echo mv
alih-alihmv
, dan kemudian menghapusecho
jika Anda senang.Pilihan lain:
itu sama dengan -i, tapi tidak akan bertanya, itu akan gagal.
sumber