bash find: dapatkan direktori file yang ditemukan

12

Saya memiliki folder induk bernama "parent_folder" dengan banyak subfolder, dalam subfolder ini adalah file bernama "foo.mp4".

Saya dapat menemukan file-file ini dengan mudah dengan melakukan ini:

mymacbook:parent_folder username$ find ./ -name "foo.mp4" -exec echo {} \;

Sekarang mengembalikan path dari setiap file, relatif ke parent_folder /

./path/to/foo.mp4

Bagaimana saya bisa mengembalikan path saja, tanpa nama file?

dubbelj
sumber
1
man find ( ACTIONS ): -printf %h Memimpin direktori nama file (semua kecuali elemen terakhir). Jika nama file tidak mengandung garis miring (karena berada di direktori saat ini)% h specifier diperluas ke "." .
Costas
Bisakah Anda menunjukkan contohnya? Haruskah saya letakkan itu di belakang '-exec' atau sebelumnya?
dubbelj
find ./ -name "foo.mp4" -printf "%h\n"akan mencetak jalur ke untuk setiap file yang ditemukan (satu demi satu). Terlebih lagi seperti biasa tidak ada yang menggunakan -exec echo {}karena itu ada -print(default bahkan dihilangkan) atau printftindakan.
Costas
2
@Costas, -printfhanya untuk GNU. OP menyebutkan OS / X (sistem BSD).
Stéphane Chazelas
@ StéphaneChazelas Terima kasih. Saya tidak tahu batasan untuk OS / X (BSD). Pengguna mac miskin miskin!
Costas

Jawaban:

20

Dengan GNUmenemukan:

 find . -name foo.mp4 -printf '%h\n'

Dengan yang lain find, asalkan nama direktori tidak mengandung karakter baris baru:

 find . -name foo.mp4 | sed 's|/[^/]*$||'

Atau:

 find . -name foo.mp4 -exec dirname {} \;

meskipun itu berarti menjalankan satu dirnameperintah per file.

Jika Anda perlu menjalankan perintah itu path, Anda bisa melakukannya (sintaks standar):

 find . -name "featured.mp4" -exec sh -c '
   for file do
     dir=${file%/*}
     ffmpeg -i "$file" -c:v libvpx -b:v 1M -c:a libvorbis "$dir" featured.webm
   done' sh {} +

Meskipun dalam hal ini, Anda mungkin dapat menggunakan -execdir(ekstensi BSD juga tersedia di GNU find), yang chdir()menuju ke direktori file:

 find . -name "featured.mp4" -execdir \
   ffmpeg -i {} -c:v libvpx -b:v 1M -c:a libvorbis . featured.webm \;

Berhati-hatilah meskipun implementasi GNU findakan diperluas {}ke ./filenamesini, yang BSD diperluas ke filename. Tidak apa-apa di sini karena nama file dilewatkan sebagai argumen untuk suatu opsi dan selalu featured.mp4tetap, tetapi untuk penggunaan lain Anda mungkin harus mempertimbangkan bahwa nama file dapat dimulai dengan -atau +(dan dipahami sebagai opsi oleh perintah) atau mengandung =(dan dipahami sebagai variabel tugas dengan awk misalnya), atau karakter lain yang menyebabkan masalah seperti ini denganperl -p/n (tidak semua dari mereka diperbaiki oleh GNU find's ./awalan meskipun dalam kasus itu), dll, yang mungkin Anda harus memperhitungkan .

Stéphane Chazelas
sumber
Ketika Anda melamar find ., sebagai dirname Anda akan memiliki. bukannya seluruh jalur.
PersianGulf
Sekarang bagaimana saya menerjemahkannya menjadi ini? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; Saya menggunakan saran kedua yang Anda sebutkan.
dubbelj
@MohsenPahlevanzadeh, OP tidak meminta path absolut, tetapi untuk dirname path.
Stéphane Chazelas
@ StéphaneChazelas Maaf untuk memilih.
PersianGulf
Terima kasih @ StéphaneChazelas. Anda membantu saya membuat antrian / batch ffmpeg
dubbelj
-1

Perintah di bawah ini juga dapat digunakan untuk mengambil detail direktori saja.

find ./ -name "foo.mp4" | rev | cut -d"/" -f2- | rev
Sekar Ramu
sumber
Tampaknya agak berlebihan untuk memanggil tiga utilitas eksternal hanya untuk memotong sebuah string.
Kusalananda