bash find: отримати каталог знайденого файлу


12

У мене є батьківська папка під назвою "parent_folder" з великою кількістю папок, у цих підпапках - файл з назвою "foo.mp4".

Я легко знаходжу ці файли, зробивши це:

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

Тепер, що повертає шлях кожного файлу, відносно parent_folder /

./path/to/foo.mp4

Як я можу повернути лише шлях без назви файла?


1
man find ( ACTIONS ): -printf %h провідні каталоги імені файлу (усі, крім останнього елемента). Якщо ім'я файлу не містить косої риски (оскільки він знаходиться в поточній директорії), специфікатор% h розширюється на ". .
Костас

Чи можете ви показати приклад цього? Чи слід це ставити за "-exec" або раніше?
dubbelj

find ./ -name "foo.mp4" -printf "%h\n"буде друкувати шлях до кожного знайденого файлу (по одному рядку). Більше, як зазвичай, ніхто не використовує, -exec echo {}тому є -print(за замовчуванням навіть пропущено) або printfдії.
Костас

2
@Costas - -printfце лише GNU. Згадування ОП про OS / X (система BSD).
Стефан Шазелас

@ StéphaneChazelas Спасибі Я не знав такого обмеження для OS / X (BSD). Бідні користувачі Mac!
Костас

Відповіді:


20

З GNUпошуку:

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

З іншими finds, надані імена каталогів не містять символів нового рядка:

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

Або:

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

хоча це означає виконання однієї dirnameкоманди на файл.

Якщо вам потрібно виконати команду на цьому path, ви можете зробити (стандартний синтаксис):

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

Хоча в цьому випадку ви можете скористатися -execdir(розширення BSD також доступне в GNU find), яке chdir()знаходиться в каталозі файлу:

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

Остерігайтеся , однак , що в той час як реалізація ГНУ findбуде розширюватися , {}щоб ./filenameтут, BSD з них розширюватися filename. Це нормально тут , як ім'я файлу передається в якості аргументу опції і завжди в featured.mp4будь-якому випадку, але і для інших використань ви , можливо , доведеться взяти до уваги , що ім'я файлу може починатися з -або +(і слід розуміти в якості опції по команді) або містити =(і розуміється як присвоєння змінної, наприклад, awk), або інші символи, що викликають подібні проблемиperl -p/n (не всі вони виправлені префіксом GNU find, ./хоча в цьому випадку) тощо, тощо, які, можливо, доведеться враховувати. .


Коли ви find .подасте заявку , у вас буде dirname. замість цілого шляху.
PersianGulf

А тепер як би це перекласти на це? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; Я використовую другу пропозицію, яку ви згадали.
dubbelj

@MohsenPahlevanzadeh, ОП просила не абсолютний шлях, а dirname шляху.
Стефан Шазелас

@ StéphaneChazelas Вибачте за те, що я проголосив.
PersianGulf

Спасибі @ StéphaneChazelas Ви допомогли мені зробити чергу / партію ffmpeg
dubbelj

-1

Нижче команда також може бути використана для отримання лише деталей каталогу.

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

Здається трохи зайвим викликати три зовнішні утиліти просто для обрізки рядка.
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.