trova non ricorsivo quando il file in alto


8

Immagina un albero delle fonti. Ci sono file xml ovunque.

Ma poiché c'è un XYZ.xml nella radice di questo albero, non troverà i miei file xml.

find -iname *.xml

ritorna

./XYZ.xml

invece di

./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml

1
Da man find: Nota che dovresti ovviamente citare i pattern, altrimenti la shell espanderà tutti i caratteri jolly in essi.
artdanil,

Risposte:


18
find -iname '*.xml'

In caso contrario, i tuoi si espande shell *.xmla XYZ.xml, e il comando che in realtà viene eseguito è

find -iname XYZ.xml

Il motivo per cui funziona se non ci sono file XML nella directory corrente è che le shell generalmente lasciano caratteri jolly non espansi se non corrispondono a nulla. In generale, ogni volta che si desidera caratteri jolly per essere ampliato con un programma diverso dal shell (ad esempio da find, tar, scpe così via) è necessario citarli in modo che la shell non cercherà di espandere il loro sé.


1
Grazie, è così semplice, ma mi chiedo come aggirarlo per mesi. L'ho trovato davvero strano, e per essere un comportamento molto incoerente, ma ora capisco perché non è trovato, ma è colpa di Bash.
Olivier Toupin,

2
Non è di per sé "colpa" di Bash, ma la tua per non aver citato i caratteri jolly che volevi passare come argomenti. Questo vale per tutti i programmi che accettano l'input della shell. La shell li espande come globs a meno che non siano citati o fuggiti.
Caleb,

1
Immagino che Olivier intendesse nel senso che è un problema di bash, non di find.
utente sconosciuto

6

Devi citare il tuo argomento in questo modo:

find ./ -name '*.xml'

in modo che venga passato per trovare invece di essere espanso dalla shell, quindi passato per trovare come versione espansa.


1
Ok, quindi se *.xmlnon corrisponde a nulla nella directory corrente, viene trasmesso letteralmente, motivo per cui funziona nell'altro caso. Risposta molto utile
Eric Wilson,

1

I caratteri jolly vengono espansi dalla shell, non dal comando. findè uno dei pochi comandi che esegue la corrispondenza dei caratteri jolly simile alla shell, a suo tempo.

Quando si esegue ls *.xml, prima la shell si espande *.xmlall'elenco dei file corrispondenti, ad esempio file1.xml file2.xml file3.xml, quindi la shell chiama lscon l'elenco di argomenti risultante file1.xml file2.xml file3.xml. Ecco perché vedi lo stesso elenco di nomi di file echo *.xml, anche se echonon sa nulla dei file e non importa se i suoi argomenti sono nomi di file.

Quando corri find . -name "*.xml":

  1. La shell analizza la riga di comando per riconoscere caratteri speciali e suddividerla in parole e punteggiatura. Qui c'è solo una lista di parole find, ., -name, *.xmldove il *è citato. Dal momento che *è citato, è un personaggio ordinario per quanto riguarda la shell.
  2. Le piste di shell il comando findcon l'elenco specificato di argomenti: ., -name, *.xml.
  3. findcerca i file il cui nome corrisponde al modello *.xmlin qualsiasi directory nella directory corrente.

Quando esegui find . -name *.xmle non ci sono file corrispondenti *.xml:

  1. La shell analizza la riga di comando per riconoscere caratteri speciali e suddividerla in parole e punteggiatura. Qui c'è solo una lista di parole find, ., -name, *.xmldove la *non è citato.
  2. Poiché la parola *.xmlcontiene un carattere jolly non quotato, la shell esegue la generazione del nome file. Poiché non ci sono nomi di file corrispondenti, il modello rimane non espanso.
  3. La shell esegue il comando findcon l'elenco risultante degli argomenti, che è ., -name, *.xml.
  4. findcerca i file il cui nome corrisponde al modello *.xmlin qualsiasi directory nella directory corrente.

Quando si esegue find . -name *.xmle la directory corrente contiene file1.xml, file2.xmle file3.xml:

  1. La shell analizza la riga di comando per riconoscere caratteri speciali e suddividerla in parole e punteggiatura. Qui c'è solo una lista di parole find, ., -name, *.xmldove la *non è citato.
  2. Poiché la parola *.xmlcontiene un carattere jolly non quotato, la shell esegue la generazione del nome file: *.xmlviene sostituita dall'elenco dei nomi file corrispondenti.
  3. La shell esegue il comando findcon l'elenco risultante degli argomenti, che è ., -name, file1.xml, file2.xml, file3.xml.
  4. findsi lamenta di un errore di sintassi quando raggiunge file2.xml.

Quando si esegue find . -name *.xmle la directory corrente contiene un singolo file corrispondente file.xml:

  1. La shell analizza la riga di comando per riconoscere caratteri speciali e suddividerla in parole e punteggiatura. Qui c'è solo una lista di parole find, ., -name, *.xmldove la *non è citato.
  2. Poiché la parola *.xmlcontiene un carattere jolly non quotato, la shell esegue la generazione del nome file: *.xmlviene sostituita dall'elenco dei nomi file corrispondenti.
  3. La shell esegue il comando findcon l'elenco risultante degli argomenti, che è ., -name, file.xml.
  4. findvede un comando perfettamente valido, ma probabilmente non è quello che volevi: ti findviene detto di cercare i file chiamati file.xmlin qualsiasi directory, di non cercare alcuna corrispondenza di file *.xml.

(La valutazione e l'espansione della shell hanno molte altre funzionalità. Ho citato solo quelle rilevanti qui.)

(Quello che descrivo è il comportamento predefinito delle shell più comuni: sh, bash, dash, ksh, ... Alcune shell possono essere configurate per visualizzare un errore invece di eseguire un comando con caratteri jolly non espansi o per espandere un carattere jolly non corrispondente in un vuoto elenco. Nessuno di questi sarebbe di aiuto qui.)


-1

Funziona su Solaris 10:

find /directory-to-search/* -prune -name "*gz"


Questo non cercherebbe i nomi che finiscono con .xml.
Kusalananda

-2

Vi preghiamo di provare:

find ./ -name *.xml

L'ho appena provato, stesso risultato.
Eric Wilson,

L'ho provato e funziona. Su GNU bash 4.2.8
bbaja42

3
Questo non funziona quando il glob corrisponde a qualcosa nella directory corrente. È la sintassi sbagliata! L' *dovrebbe sempre essere quotate o sfuggiti a passarlo da trovare.
Caleb,
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.