Come rilevare se "trova" ha trovato delle corrispondenze?


16

Esiste un mezzo idiomatico per rilevare se "trova" ha trovato delle corrispondenze? Attualmente sto usando

COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then

ma questo mi sembra un po 'indiretto. Inoltre, vorrei trovare di interrompere la ricerca una volta trovata una corrispondenza, in modo da non perdere tempo e fatica. Devo solo sapere se ci sono file corrispondenti.

Aggiornamento: ho fatto l'errore di scrivere la mia domanda senza il codice davanti a me: lo uso wc -lin un caso diverso, dove ho bisogno di conoscere il numero totale di file trovati comunque. Nel caso in cui sto solo testando se ci sono delle partite, stavo usando if [ -z $(find …) ].

Risposte:


17

Se sai di avere GNU find, usalo -quit per fermarlo dopo la prima partita.

Portabilmente, convoglia l'output di findin head -n 1. In questo modo findmorirà di un tubo rotto dopo alcune partite (quando è riempito headil buffer di input).

In entrambi i casi, non è necessario wcverificare se una stringa è vuota, la shell può farlo da sola.

if [ -n "$(find … | head -n 1)" ]; then …

Interessante ... Ho pensato di -napplicarlo solo alle variabili "definite" ($ abc, $ xyz, ecc.), Ma suppongo che $ (...) sia una variabile temporanea "definita" .. +1 ... (e ho appena leggi di recente che l'utilizzo -nè rischioso, a meno che tu non sia sicuro che la variabile non sia già stata dichiarata e sia "inutilizzata" ... ma un temp non avrà questa possibilità ... non inizializzato vs. vuoto
Peter

2
@fred: al contrario, -nverifica se una stringa è vuota, non ha nulla a che fare con le variabili. Quello che hai letto probabilmente diceva che l'utilizzo -nnon verifica se una variabile è definita: -n "$foo"è falsa se foodefinita ma vuota e visualizza un messaggio di errore sotto set -u. [ -n "${foo+1}" ]verifica in modo affidabile se fooè impostato, ma trattare le variabili vuote e non impostate in modo identico è di solito una buona idea: [ -n "${foo:+1}" ]o solo [ -n "$foo" ]se non sei preoccupato set -u.
Gilles 'SO- smetti di essere malvagio'

Grazie! Non ho a -quitdisposizione, ma il piping head -n 1funziona (come fa head -c 1, che si ferma anche prima, ma probabilmente con benefici trascurabili). Inoltre, ho fatto l'errore di scrivere la mia domanda senza il codice davanti a me: lo uso wc -lin un caso diverso, dove ho bisogno di sapere il numero totale di file trovati. Nel caso in cui sto solo testando se ci sono delle partite, stavo usando if [ -z `find … ` ].
Chris Page

6

Puoi usare l' -quitazione per fermarti dopo la prima partita. Probabilmente vorrai combinarlo con un'altra azione (come -print) o non sarai in grado di dire se ha trovato qualcosa.

Ad esempio, find ... -print -quitstamperà il percorso del primo file corrispondente e quindi uscirà. Oppure, puoi usare -printf 1 -quitper stampare 1 se c'è una corrispondenza e niente se non c'è.

findLo stato di uscita riflette se ci sono stati errori durante la ricerca e non se ha trovato qualcosa, quindi devi controllare il suo output per vedere se c'è una corrispondenza.


-quitè un'estensione GNU. Non funzionerà su sistemi che utilizzano altre implementazioni di find (1), come OS X, i BSD e probabilmente la maggior parte degli Unices commerciali.
Warren Young,

Grazie, è utile sapere nel caso in cui sto usando un altro sistema. Sfortunatamente, né -quit né -printf sono disponibili sul mio (Mac OS X).
Chris Page

4

Exit 0 è facile con find, exit> 0 è più difficile perché ciò accade di solito solo con un errore. Tuttavia possiamo farlo accadere:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

Si noti che questa soluzione è più performante rispetto all'utilizzo di una subshell; eseguire false è certamente più veloce che eseguire anche Dash:

$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]

$ strace dash alfa.sh | wc -l
807

$ strace dash bravo.sh | wc -l
1141

$ strace dash charlie.sh | wc -l
1184

$ strace dash delta.sh | wc -l
1194

0

Puoi avvolgerlo nella condizione di shell, ad esempio:

[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found

Dov'è la ...tua condizione di partita, ad es -name *.txt.

Alcuni altri esempi:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
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.