bash find: bulunan dosyanın dizinini al


12

Alt klasörleri çok "parent_folder" adlı bir üst klasörü var, bu alt klasörlerde "foo.mp4" adlı bir dosya.

Bunu yaparak bu dosyaları kolayca bulabilirsiniz:

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

Artık bu, parent_folder /

./path/to/foo.mp4

Dosya adı olmadan sadece yolu nasıl döndürebilirim?


1
man find ( EYLEMLER ): -printf %h Dosya adının önde gelen dizinleri (son öğe hariç tümü). Dosya adı eğik çizgi içermiyorsa (geçerli dizinde olduğundan)% h belirteci "." .
Costas

Buna bir örnek gösterebilir misiniz? Bunu '-exec' arkasına mı yoksa daha öncesine mi koymalıyım?
dubbelj

find ./ -name "foo.mp4" -printf "%h\n"bulunan her dosya için yolu (satır satır) yazdırır. Her zamanki gibi daha fazla kimse -exec echo {}bu nedenle kullanmaz -print(varsayılan bile atlanır) veya printfeylem vardır.
Costas

2
@Costas, -printfyalnızca GNU'dur . OP, OS / X'den (bir BSD sistemi) bahsediyor.
Stéphane Chazelas

@ StéphaneChazelas Teşekkürler. OS / X (BSD) için böyle bir sınırlama bilmiyordum. Kötü zavallı Mac kullanıcıları!
Costas

Yanıtlar:


20

İle GNUfind:

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

Diğer finds'lerde, sağlanan dizin adları yeni satır karakterleri içermez:

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

Veya:

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

ancak bu dirnamedosya başına bir komut çalıştırmak anlamına gelir .

Bunun için bir komut çalıştırmanız gerekiyorsa path, yapabilirsiniz (standart sözdizimi):

 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 {} +

Bu durumda, dosyanın dizininde bulunan -execdir(GNU'da da bulunan bir BSD uzantısı find) chdir()kullanabilirsiniz:

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

GNU uygulanması sırasında bu olsa sakının findgenişleyecektir {}için ./filenameburaya, BSD olanları genişletmek filename. Dosya adı bir seçeneğe argüman olarak iletildiğinden ve her zaman her featured.mp4durumda olduğu için sorun yok, ancak diğer kullanımlar için dosya adının başlayabileceğini -veya +(ve komut tarafından bir seçenek olarak anlaşılabileceğini) veya içerdiğini dikkate almanız gerekebilir. =(ve örneğin awk değişken ataması olarak anlaşılacaktır) veya diğer karakterler neden olan bu tür bir sorunuperl -p/n GNU'den bunların hepsi sabit ( find's./ önek olsa bu durumda) dikkate almak gerekebilir vb, .


Başvurduğunuzda find ., dirname olarak sahip olacaksınız. tüm yol yerine.
PersianGulf

Şimdi bunu nasıl tercüme ederim? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; Bahsettiğiniz ikinci öneriyi kullanıyorum.
dubbelj

@MohsenPahlevanzadeh, OP mutlak bir yol istemedi, ama yolun adını istedi.
Stéphane Chazelas

@ StéphaneChazelas Oylama yaptığım için üzgünüm.
PersianGulf

Teşekkürler StéphaneChazelas. Bana bir ffmpeg kuyruğu / toplu iş yapmak yardımcı oldu
dubbelj

-1

Aşağıdaki komut sadece dizin ayrıntılarını almak için de kullanılabilir.

find ./ -name "foo.mp4" | rev | cut -d"/" -f2- | rev

Bir dizeyi kırpmak için üç harici yardımcı programı çağırmak biraz aşırı görünüyor.
Kusalananda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.