L'approccio di @ meuh è inefficiente in quanto il suo -maxdepth 1approccio consente ancora di findleggere il contenuto delle directory al livello 1 per ignorarle successivamente. Inoltre non funzionerà correttamente con alcune findimplementazioni (incluso GNU find) se alcuni nomi di directory contengono sequenze di byte che non formano caratteri validi nelle impostazioni locali dell'utente (come per i nomi di file con una codifica di caratteri diversa).
find . \( -name . -o -prune \) -extra-conditions-and-actions
è il modo più canonico di implementare GNU -maxdepth 1(o FreeBSD -depth -2).
In genere, però, è -depth 1tu che vuoi ( -mindepth 1 -maxdepth 1) come non vuoi considerare .(profondità 0), e poi è ancora più semplice:
find . ! -name . -prune -extra-conditions-and-actions
Perché -maxdepth 2diventa:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Ed è qui che corri nei problemi con i personaggi non validi.
Ad esempio, se hai una directory chiamata Stéphanema écodificata nel set di caratteri iso8859-1 (aka latin1) (0xe9 byte) come era più comune in Europa occidentale e in America fino alla metà degli anni 2000, allora quel byte 0xe9 non è un carattere valido in UTF-8. Quindi, nelle versioni locali UTF-8, il *carattere jolly (con alcune findimplementazioni) non corrisponderà Stéphanepoiché *è 0 o più caratteri e 0xe9 non è un carattere.
$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
Il mio find(quando l'uscita va su un terminale) visualizza quel byte 0xe9 non valido come ?sopra. Potete vedere che St<0xe9>phane/Chazelasnon era pruned.
Puoi aggirare il problema facendo:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Tuttavia, ciò influisce su tutte le impostazioni locali finde su qualsiasi applicazione in esecuzione (come tramite i -execpredicati).
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
Ora, ho davvero un -maxdepth 2ma nota come l'é nel secondo Stéphane correttamente codificato in UTF-8 viene visualizzato come ??byte 0xc3 0xa9 (considerati come due singoli caratteri indefiniti nella locale C) della codifica UTF-8 di é caratteri non stampabili nella locale C.
E se avessi aggiunto un -name '????????', avrei ottenuto Stéphane sbagliato (quello codificato in iso8859-1).
Per applicare a percorsi arbitrari invece di ., devi fare:
find some/dir/. ! -name . -prune ...
per -mindepth 1 -maxdepth 1o:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
per -maxdepth 2.
Vorrei ancora fare un:
(cd -P -- "$dir" && find . ...)
In primo luogo perché ciò rende i percorsi più brevi, il che rende meno probabile che si verifichino percorsi troppo lunghi o che elenchi problemi troppo lunghi , ma anche per aggirare il fatto che findnon può supportare argomenti di percorso arbitrari (tranne -fcon FreeBSD find) in quanto si soffocano valori di $dirlike !o -print...
In -ocombinazione con la negazione è un trucco comune per eseguire due serie indipendenti di -condition/ -actionin find.
Se si desidera eseguire -action1su riunioni di file -condition1e indipendentemente -action2su riunioni di file -condition2, non è possibile eseguire:
find . -condition1 -action1 -condition2 -action2
Come -action2verrebbe eseguito solo per i file che soddisfano entrambe le condizioni.
Né:
find . -contition1 -action1 -o -condition2 -action2
Come -action2non verrebbe eseguito per i file che soddisfano entrambe le condizioni.
find . \( ! -condition1 -o -action1 \) -condition2 -action2
funziona come \( ! -condition1 -o -action1 \)risolverebbe vero per ogni file. Questo presuppone -action1è un'azione (come -prune, -exec ... {} +) che restituisce sempre vero . Per azioni del genere -exec ... \;può sembrare falso , potresti voler aggiungere un altro -o -somethingdove -somethingè innocuo ma restituisce vero come -truein GNU findo -links +0o -name '*'(anche se nota il problema relativo ai caratteri non validi sopra).
-depth -2,-depth 1... potrebbe essere visto come migliore di GNU-maxdepth/-mindepth