El enfoque de @meuh es ineficiente ya que su -maxdepth 1enfoque todavía permite findleer el contenido de los directorios en el nivel 1 para luego ignorarlos de lo contrario. Tampoco funcionará correctamente con algunas findimplementaciones (incluida GNU find) si algunos nombres de directorio contienen secuencias de bytes que no forman caracteres válidos en la configuración regional del usuario (como para los nombres de archivo en una codificación de caracteres diferente).
find . \( -name . -o -prune \) -extra-conditions-and-actions
es la forma más canónica de implementar GNU -maxdepth 1(o FreeBSD -depth -2).
En general, es lo -depth 1que quieres ( -mindepth 1 -maxdepth 1), ya que no quieres considerarlo .(profundidad 0), y luego es aún más simple:
find . ! -name . -prune -extra-conditions-and-actions
Porque -maxdepth 2eso se convierte en:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Y ahí es donde se ejecutan los problemas de caracteres no válidos.
Por ejemplo, si tiene un directorio llamado Stéphanepero que éestá codificado en el conjunto de caracteres iso8859-1 (también conocido como latin1) (0xe9 byte) como era más común en Europa occidental y América hasta mediados de la década de 2000, entonces ese byte 0xe9 no es un Carácter válido en UTF-8. Por lo tanto, en las configuraciones regionales UTF-8, el *comodín (con algunas findimplementaciones) no coincidirá, Stéphaneya que *es 0 o más caracteres y 0xe9 no es un carácter.
$ 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
Mi find(cuando la salida va a una terminal) muestra ese byte 0xe9 inválido como el ?anterior. Puedes ver que St<0xe9>phane/Chazelasno fue pruned.
Puede solucionarlo haciendo:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Pero tenga en cuenta que eso afecta a toda la configuración regional findy a cualquier aplicación que ejecute (como a través de los -execpredicados).
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
Ahora, realmente obtengo un mensaje, -maxdepth 2pero tenga en cuenta cómo el é en el segundo Stéphane codificado correctamente en UTF-8 se muestra ??como los 0xc3 0xa9 bytes (considerados como dos caracteres indefinidos individuales en el entorno C) de la codificación UTF-8 de é caracteres no imprimibles en la configuración regional C.
Y si hubiera agregado un -name '????????', habría obtenido el Stéphane incorrecto (el codificado en iso8859-1).
Para aplicar a rutas arbitrarias en lugar de hacerlo ., haría lo siguiente:
find some/dir/. ! -name . -prune ...
para -mindepth 1 -maxdepth 1o:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
para -maxdepth 2.
Todavía haría un:
(cd -P -- "$dir" && find . ...)
Primero porque eso hace que las rutas sean más cortas, lo que hace que sea menos probable que se encuentre con una ruta demasiado larga o que contengafind argumentos demasiado largos , pero también que evite el hecho de que no puede admitir argumentos de ruta arbitraria (excepto -fcon FreeBSD find) ya que se ahogará valores de me $dirgusta !o -print...
En -ocombinación con la negación es un truco común para ejecutar dos conjuntos independientes de -condition/ -actionin find.
Si desea ejecutar -action1en reunión de archivos -condition1e independientemente -action2en reunión de archivos -condition2, no puede hacer:
find . -condition1 -action1 -condition2 -action2
Como -action2solo se ejecutaría para archivos que cumplan ambas condiciones.
Ni:
find . -contition1 -action1 -o -condition2 -action2
Como -action2no se ejecutaría para archivos que cumplan ambas condiciones.
find . \( ! -condition1 -o -action1 \) -condition2 -action2
funciona como \( ! -condition1 -o -action1 \)se resolvería a verdadero para cada archivo. Eso supone que -action1es una acción (como -prune, -exec ... {} +) que siempre devuelve verdadero . Por acciones como -exec ... \;que pueden volver falsa , es posible que desee agregar otro -o -somethingdonde -somethinges inofensivo pero devuelve cierto como -trueen GNU findo -links +0o -name '*'(aunque tenga en cuenta la cuestión acerca de caracteres no válidos anteriores).
-depth -2,-depth 1... el enfoque podría ser visto como mejor que el de GNU-maxdepth/-mindepth