bash find: pobierz katalog znalezionego pliku

12

Mam folder nadrzędny o nazwie „folder nadrzędny” z dużą liczbą podfolderów, w tych podfolderach znajduje się plik o nazwie „foo.mp4”.

Mogę łatwo znaleźć te pliki, wykonując następujące czynności:

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

Teraz zwraca ścieżkę do każdego pliku względem folderu nadrzędnego /

./path/to/foo.mp4

Jak mogę zwrócić samą ścieżkę bez nazwy pliku?

dubbelj
źródło
1
man find ( AKCJE ): -printf %h Wiodące katalogi o nazwie pliku (wszystkie oprócz ostatniego elementu). Jeśli nazwa pliku nie zawiera ukośników (ponieważ znajduje się w bieżącym katalogu), specyfikator% h rozwija się do „.” .
Costas
Czy możesz podać przykład? Czy powinienem to umieścić za „-exec” czy wcześniej?
dubbelj
find ./ -name "foo.mp4" -printf "%h\n"wypisze ścieżkę do każdego znalezionego pliku (jeden po wierszu). Co więcej, jak zwykle nikt nie używa, -exec echo {}dlatego jest -print(domyślnie nawet pominięty) lub printfdziałanie.
Costas
2
@Casas, -printfjest tylko GNU. OP wspomina OS / X (system BSD).
Stéphane Chazelas
@ StéphaneChazelas Thanks. Nie znałem takich ograniczeń dla OS / X (BSD). Biedni biedni użytkownicy komputerów Mac!
Costas

Odpowiedzi:

20

Z GNUfind:

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

W przypadku innych findliter podane nazwy katalogów nie zawierają znaków nowej linii:

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

Lub:

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

oznacza to jednak uruchomienie jednego dirnamepolecenia na plik.

Jeśli musisz uruchomić komendę path, możesz to zrobić (standardowa składnia):

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

Chociaż w tym przypadku możesz być w stanie użyć -execdir(rozszerzenie BSD dostępne również w GNU find), które chdir()znajduje się w katalogu pliku:

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

Uważaj jednak, że podczas gdy implementacja GNU findrozszerzy {}się ./filenametutaj, BSD rozwijają się do filename. Tutaj jest OK, ponieważ nazwa pliku jest przekazywana jako argument do opcji i zawsze featured.mp4tak jest, ale w innych zastosowaniach może być konieczne wzięcie pod uwagę, że nazwa pliku może zaczynać się od -lub +(i być rozumiana jako opcja przez polecenie) lub zawierać =(i należy to rozumieć na przykład jako przypisanie zmiennej przez awk) lub inne znaki powodujące tego rodzaju problem zperl -p/n (nie wszystkie z nich naprawione przez prefiks GNU find, ./chociaż w tym przypadku) itp., które możesz wziąć pod uwagę .

Stéphane Chazelas
źródło
Kiedy złożysz podanie find ., będziesz miał nazwę dirname. zamiast całej ścieżki.
PersianGulf
Jak mam to na to przetłumaczyć? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; Korzystam z drugiej sugestii, o której wspomniałeś.
dubbelj
@MohsenPahlevanzadeh, OP nie poprosił o bezwzględną ścieżkę, ale o nazwę ścieżki.
Stéphane Chazelas
@ StéphaneChazelas Przepraszamy za głosowanie odrzucone.
PersianGulf
Dzięki @ StéphaneChazelas.
Pomogłeś
-1

Poniższe polecenie może również służyć do pobierania tylko szczegółów katalogu.

find ./ -name "foo.mp4" | rev | cut -d"/" -f2- | rev
Sekar Ramu
źródło
Wywołanie trzech zewnętrznych narzędzi tylko w celu przycięcia łańcucha wydaje się nieco przesadne.
Kusalananda