Ya, saya sedang memilah musik saya. Saya telah mengatur segalanya dengan indah dalam mantra berikut: /Artist/Album/Track - Artist - Title.ext
dan jika ada, sampulnya ada /Artist/Album/cover.(jpg|png)
.
Saya ingin memindai semua direktori tingkat kedua dan menemukan yang tidak memiliki penutup. Pada level kedua, maksud saya saya tidak peduli jika /Britney Spears/
tidak memiliki cover.jpg, tetapi saya akan peduli jika /Britney Spears/In The Zone/
tidak memilikinya.
Jangan khawatir tentang pengunduhan sampulnya (itu adalah proyek yang menyenangkan bagi saya besok). Saya hanya peduli tentang kemalasan bash yang mulia tentang contoh terbalik find
.
Jawaban:
Kasus 1: Anda tahu nama file yang tepat untuk dicari
Gunakan
find
dengantest -e your_file
untuk memeriksa apakah ada file. Misalnya, Anda mencari direktori yang tidak adacover.jpg
di dalamnya:Ini case sensitif sekalipun.
Kasus 2: Anda ingin lebih fleksibel
Anda tidak yakin dengan kasusnya, dan ekstensi mungkin
jPg
,png
...Penjelasan:
sh
untuk setiap direktori karena pemipaan tidak memungkinkan saat menggunakanfind
ls -1 "{}"
keluaran hanya nama file direktorifind
saat ini melintasiegrep
(bukangrep
) menggunakan ekspresi reguler yang diperluas;-i
membuat case pencarian tidak sensitif,-q
membuatnya menghilangkan output apa pun"^cover\.(jpg|png)$"
adalah pola pencarian. Dalam contoh ini, ini cocok dengan misalnyacOver.png
,Cover.JPG
ataucover.png
. The.
harus melarikan diri jika tidak berarti bahwa itu cocok setiap karakter.^
menandai awal baris,$
akhirnyaContoh pola pencarian lain untuk egrep :
Gantikan
egrep -i -q "^cover\.(jpg|png)$"
bagian dengan:egrep -i -q "cover\.(jpg|png)$"
: Juga cocokcd_cover.png
,album_cover.JPG
...egrep -q "^cover\.(jpg|png)$"
: Cocokcover.png
,,cover.jpg
tapi TIDAKCover.jpg
(sensitivitas huruf tidak dimatikan)egrep -iq "^(cover|front)\.jpg$"
: cocok misalnyafront.jpg
,Cover.JPG
tetapi tidakCover.PNG
Untuk info lebih lanjut tentang ini, lihat Ekspresi Reguler .
sumber
test
.-exec bash -c '[[ -n $(find "{}" -iname "cover.*") ]]' \;
tapi itu cukup kotor dalam hal optimasi. Tapi itu berhasil.test
banyak-o EXPRESSION
permintaan ATAU ... mis.:test -e "{}/cover.jpg" -o -e "{}/cover.png"
Yang lebih baik daripada melakukan pencarian penuh tetapi itu tetap peka.$
dalam nama dir (Ke $ ha, misalnya).Sederhana, itu terjadi. Yang berikut mendapat daftar direktori dengan sampul dan membandingkannya dengan daftar semua direktori tingkat kedua. Baris yang muncul di kedua "file" ditekan, meninggalkan daftar direktori yang perlu ditutupi.
Hore.
Catatan:
comm
Argumennya adalah sebagai berikut:-1
menekan baris unik ke file1-2
menekan baris unik ke file2-3
menekan garis yang muncul di kedua filecomm
hanya mengambil file, maka<(...)
metode input kooky . Ini mem-pipe konten melalui file [temporer] sungguhan.comm
membutuhkan input yang diurutkan atau tidak berfungsi danfind
tidak menjamin pesanan. Itu juga harus unik.find
Operasi pertama dapat menemukan beberapa filecover.*
sehingga ada entri duplikat.sort -u
dengan cepat mengacaknya menjadi satu. Temuan kedua selalu akan menjadi unik.dirname
adalah alat yang berguna untuk mendapatkan dir file tanpa menggunakansed
(et al).find
dancomm
keduanya agak berantakan dengan output mereka. Finalsed
ada di sana untuk membersihkan semuanya sehingga Anda pergi denganArtist/Album
. Ini mungkin atau mungkin tidak diinginkan untuk Anda.sumber
find
mungkin dapat disederhanakanfind ~/Music/ -iname 'cover.*' -printf '%h\n'
, menghindari kebutuhandirname
. meskipundirname
berguna di tempat lain.Ini jauh lebih baik untuk diselesaikan dengan globbing daripada dengan find.
Sekarang anggaplah Anda tidak memiliki file liar dalam struktur yang bagus ini. Direktori saat ini hanya berisi subdirektori artis, dan direktori tersebut hanya berisi subdirektori album. Maka kita dapat melakukan sesuatu seperti ini:
The
<(...)
sintaks proses substitusi Bash: itu memungkinkan Anda menggunakan perintah di tempat argumen berkas. Ini memungkinkan Anda memperlakukan output dari suatu perintah sebagai file. Jadi kita bisa menjalankan dua program, dan mengambil diff mereka, tanpa menyimpan output mereka dalam file sementara. Thediff
Program berpikir itu bekerja dengan dua file, tapi sebenarnya itu membaca dari dua pipa.Perintah yang menghasilkan masukan tangan kanan untuk
diff
,printf "%s\n" */*
, hanya berisi daftar direktori album. Perintah tangan kiri beralih melalui*.cover
jalur dan mencetak nama direktori mereka.Uji coba:
Aha,
a/b
danfoo/bar
direktori tidak punyacover.jpg
.Ada beberapa kasus sudut yang rusak, seperti itu secara default
*
mengembang sendiri jika tidak cocok. Ini bisa diatasi dengan Bashset -o nullglob
.sumber
comm
akan lebih bersih dari itudiff
?comm -3 <(printf "%s\n" */*/cover* | sed -r 's/\/[^\/]+$//' | sort -u) <(printf "%s\n" */*)
tampaknya seperti kompromi yang masuk akal tanpadiff
bulu. Namun, ini sedikit lebih lambat dari penemuan ganda saya.Akan menampilkan semua direktori yang tidak memiliki file txt di dalamnya.
sumber