bash find: ottiene la directory del file trovato


12

Ho una cartella principale denominata "parent_folder" con molte sottocartelle, in queste sottocartelle c'è un file chiamato "foo.mp4".

Posso trovare facilmente questi file facendo questo:

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

Ora che restituisce il percorso di ciascun file, relativo a parent_folder /

./path/to/foo.mp4

Come posso restituire solo il percorso, senza il nome file?


1
man find ( AZIONI ): -printf %h directory principali del nome del file (tutte tranne l'ultimo elemento). Se il nome del file non contiene barre (poiché si trova nella directory corrente), l'identificatore% h si espande in "." .
Costas,

Potresti mostrarne un esempio? Dovrei metterlo dietro '-exec' o prima?
dubbelj,

find ./ -name "foo.mp4" -printf "%h\n"stamperà il percorso per ogni file trovato (uno per riga). Più come al solito nessuno usa -exec echo {}quindi c'è -print(default anche omesso) o printfazione.
Costas,

2
@Costas, -printfè solo GNU. L'OP menziona OS / X (un sistema BSD).
Stéphane Chazelas,

@ StéphaneChazelas Grazie. Non conoscevo tale limitazione per OS / X (BSD). Poveri utenti poveri di mac!
Costas,

Risposte:


20

Con GNUtrovare:

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

Con altri messaggi find, i nomi delle directory forniti non contengono caratteri di nuova riga:

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

O:

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

sebbene ciò significhi eseguire un dirnamecomando per file.

Se è necessario eseguire un comando su questo path, è possibile eseguire (sintassi standard):

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

Sebbene in questo caso, potresti essere in grado di usare -execdir(un'estensione BSD disponibile anche in GNU find), che chdir()è nella directory del file:

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

Attenzione però che, mentre l'implementazione GNU di findsi espanderà {}a ./filenamequi, quelli BSD si espandono a filename. Va bene qui poiché il nome del file viene passato come argomento a un'opzione ed è sempre featured.mp4comunque, ma per altri usi potresti dover tenere conto del fatto che il nome del file può iniziare con -o +(ed essere compreso come un'opzione dal comando) o contenere =(ed essere intesi come un'assegnazione variabile da awk per esempio), o altri caratteri causano questo tipo di problemaperl -p/n (non tutti fissati dal GNU find's ./prefisso se in quel caso), ecc, che potrebbe essere necessario prendere in considerazione .


Quando ti candidi find ., come dirname avrai. invece dell'intero percorso.
Golfo Persico,

Ora come lo traduco in questo? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; Sto usando il secondo suggerimento che hai citato.
dubbelj,

@MohsenPahlevanzadeh, l'OP non ha chiesto un percorso assoluto, ma il nome dir del percorso.
Stéphane Chazelas,

@ StéphaneChazelas Ci scusiamo per il voto basso.
Golfo Persico,

Grazie @ StéphaneChazelas. Mi hai aiutato a creare una coda / batch ffmpeg
dubbelj,

-1

Il comando seguente può anche essere usato per recuperare solo i dettagli della directory.

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

Sembra un po 'eccessivo chiamare tre utility esterne solo per tagliare una stringa.
Kusalananda
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.