Saya baru-baru ini mengkonversi semua file FLAC saya ke tingkat pengambilan sampel yang lebih rendah dari 44,1 kHz dan kedalaman bit 24 bit (karena iPhone / iPod tidak mendukung apa pun di atas itu) menggunakan XLD pada Mac OS 10.7 (Lion).
Meskipun saya mengatakan XLD untuk menimpa semua file sebelumnya, XLD menambahkan (1)
di akhir file seperti dari
some_song.m4a
untuk
some_song(1).m4a
Jadi sekarang saya ingin menghapus itu (1)
dari semua file FLAC yang saya konversi.
Saya tahu saya mungkin bisa menggunakan beberapa program atau bahkan AppleScript untuk mengganti nama file, tapi saya ingin belajar menggunakan cara baris perintah sekolah yang lama.
Saya tahu bahwa find . -name *\(1\).m4a
akan mengambil semua file FLAC yang dikonversi.
Selanjutnya saya tahu saya harus melakukan sesuatu dengan -exec
dan mv
mengubah nama semua file yang ditemukan. Tapi apa yang saya tidak tahu adalah bagaimana menjaga nama file asli dan hanya menghapus (1)
.
Mungkin saya perlu melakukan beberapa menangkap regex grup untuk menyimpan bagian dari nama file yang saya tidak ingin modifikasi? Atau mungkin itu tidak mungkin untuk melakukan semuanya dalam satu baris dan saya harus membuat skrip shell (yang saya tidak nyaman melakukannya, tapi saya bersedia mencobanya).
Setiap tips atau saran disambut! Terima kasih!
find
) tetapi itu mungkin menyelesaikan masalah Anda yang sebenarnya (mengonversi file audio), Anda mungkin tertarik untuk melihat audiotools.sourceforge.net dan untuk contoh kasus ini (untuk macosx lion) invibe.net/ LaurentPerrinet / SciBlog / 2012-04-22Jawaban:
Jangan mencoba mengurai
find
output kecuali sebagai pilihan terakhir. Penting untuk disadari bahwa pada sistem file Unix, nama file bukan string (kesalahpahaman umum) melainkan gumpalan biner yang dapat berisi karakter apa pun kecuali/
karakter nol. Mem-parsing nama file dengan aman dan benar sudah cukup menyakitkan sehingga 99% dari waktu Anda hanya ingin menghindarinya sama sekali (lihat saja betapa berbulunyased
ekspresi dalam jawaban @ yarek dan bahkan itu tidak mencakup semua kasus) . Untungnya, dalam hal ini ada pendekatan yang jauh lebih sederhana:sumber
done
?sed
pendekatan pipa adalah ini jauh lebih aman. Ini masih lebih mudah dibaca daripada regex backslash soup, asalkan Anda memahami beberapa konstruksi skrip shell dasar.$arg
variabel membuatnya lebih mudah dibaca.find
menggunakansh
sintaks POSIX yang cukup portabel. Untuk detail lebih lanjut, Anda dapat memeriksa bagian pada Parameter Expansion , bagian tentang perintah majemuk yang menjelaskanfor
loop , dan spesifikasi POSIXfind
. Selain sumber daya itu, saya akan dengan senang hati menjawab setiap pertanyaan spesifik yang Anda miliki.Di Debian dan Ubuntu, saya bisa gunakan
rename 's/\(1\)//' *.m4a
untuk menyelesaikan masalah Anda.sumber
man rename
, tetapi sebenarnya saya tidak punyarename
:-bash: rename: command not found
(which rename
tidak menunjukkan apa-apa).man -a rename
menemukan rename (2) - syscall, dan rename (n) - perintah TCL. Ada tidak rename (1) maupun utilitas itu sendiri ada.rename
adalah skrip perl yang disertakan dengan contoh-contoh yang disertakan dalam beberapa pemasangan perl, dan beberapa distro memasukkannya dalam path karena itu adalah perintah yang mudah. (@Hobbes mungkin Anda bisa menemukannya di internet)rename
adalah biner normal (bukan perl). Namun peringatan lain adalah bahwa tidak semua versirename
mendukung regex. Versi yang saya miliki misalnya hanya memungkinkan Anda melakukan penggantian string langsung, misalnyarename '(1)' '' *.m4a
rename
Skrip Perl hanya diinstal oleh Debian dan turunannya. Sistem Linux lainnya memilikirename
utilitas yang berbeda (ditunjukkan oleh Patrick). OSX tidak memiliki keduanya.Di zsh, menggunakan zmv :
Dalam argumen kedua (nama baru),
$1
dan$2
merujuk ke grup yang(PATTERN)
di- kurung dalam pola sumber. Cara lain untuk penulisan nama ini adalahsumber
Pendekatan berikut memberi Anda kemampuan untuk melihat dulu / memangkas perintah yang dihasilkan sebelum menjalankannya, dan sangat portabel: itu harus bekerja tidak hanya pada mac, tidak hanya dengan bash, dan tidak hanya dengan GNU sed; bahkan pada sistem tanpa
find
perintah (1) dimungkinkan untuk menggantikannya dengandu
(1) tanpa masalah.Jika senang dengan perintah yang dicetak, jalankan kembali dengan
| sh -x
menambahkan.Jika khawatir tentang ruang dalam nama file, menambah s untuk melarikan diri semua ruang:
Jika karakter khusus lain diharapkan, ini akan sedikit lebih rumit:
Fungsi pertama mengkonversi semua
'
menjadi bentuk sehingga ini diambil secara harfiah ketika di tengah-tengah'...'
string. Fungsi kedua menghasilkan perintah mv yang argumennya disertakan'...'
.sumber
(
,, dan semua karakter khusus lainnya) atau menambahkan tanda kutip di sekitar nama file. Saya mencoba mengubah perintah Anda, tetapi saya tidak tahu cara menambahkan tanda kutip di kedua nama file untukmv
perintah. Salah satu output yang dihasilkan dari perintah Anda adalahmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. Dan jika saya menjalankan perintah itu saya dapatkan-bash: syntax error near unexpected token '('
.e
perintah setelah substitusi. Sebagai contohfind . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
akan mengeksekusi perintah tanpa piping kesh -x
.Berikut ini skrip kecil yang melakukannya:
sumber
`find ...`