Domanda

Sto cercando di costruire un comando find per elaborare un gruppo di file in una directory utilizzando due diversi eseguibili.Purtroppo, -exec su find non consente di utilizzare pipe o addirittura \| perché la shell interpreta prima quel carattere.

Ecco nello specifico cosa sto cercando di fare (che non funziona perché pipe termina il comando find):

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
È stato utile?

Soluzione

Prova questo

find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print

In alternativa potresti provare a incorporare la tua istruzione exec all'interno di uno script sh e poi fare:

find -exec some_script {} \;

Altri suggerimenti

Un approccio leggermente diverso sarebbe usare xargs:

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

che ho sempre trovato un po' più facile da capire e da adattare (gli argomenti -print0 e -0 sono necessari per gestire nomi di file contenenti spazi vuoti)

Questo Potrebbe (non testato) sarà più efficace dell'uso di -exec perché convoglierà l'elenco dei file a xargs e xargs si assicurerà che la riga di comando di jhead non diventi troppo lunga.

Con -exec puoi eseguire solo un singolo eseguibile con alcuni argomenti, non comandi shell arbitrari.Per aggirare questo problema, è possibile utilizzare sh -c '<shell command>'.

Tieni presente che l'uso di -exec è abbastanza inefficiente.Per ogni file trovato, il comando deve essere eseguito nuovamente.Sarebbe più efficiente se potessi evitarlo.(Ad esempio, spostando il grep fuori da -exec o trasmettere i risultati di find A xargs come suggerito da Palmino.)

Utilizzando find Il comando per questo tipo di attività forse non è l'alternativa migliore.Utilizzo frequentemente il seguente comando per trovare file che contengono le informazioni richieste:

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done

Dato che questo produce un elenco, non dovresti:

find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123

O

find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123

Metti il ​​tuo grep sui risultati di find -exec.

C'è un altro modo in cui puoi farlo, ma è anche piuttosto ghetto.

Usando l'opzione della shell extquote puoi fare qualcosa di simile a questo per trovare materiale exec e poi collegarlo a sh.

root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Ho solo pensato di aggiungerlo perché almeno per come l'ho visualizzato, era più vicino alla domanda originale dell'OP sull'uso delle pipe all'interno di exec.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top