Hace poco noté que las especificaciones POSIX parafind
no incluyen el -maxdepth
primario.
Para aquellos que no están familiarizados con él, el objetivo de la -maxdepth
primaria es restringir cuántos niveles de profundidad find
descenderán. -maxdepth 0
da como resultado que solo se procesen los argumentos de la línea de comandos; -maxdepth 1
solo manejaría los resultados directamente dentro de los argumentos de la línea de comando, etc.
¿Cómo puedo obtener el comportamiento equivalente al -maxdepth
primario no POSIX usando solo las opciones y herramientas especificadas por POSIX?
(Nota: Por supuesto, puedo obtener el equivalente de -maxdepth 0
solo usarlo -prune
como primer operando, pero eso no se extiende a otras profundidades).
-depth -2
,-depth 1
... el enfoque podría ser visto como mejor que el de GNU-maxdepth
/-mindepth
-maxdepth
/-mindepth
, hay alternativas razonables (tenga en cuenta que-path
es una adición reciente a POSIX). Las alternativas para-timexy
o-mtime -3m
(o-mmin -3
) son mucho más engorrosas. A algunos les gusta-execdir
/-delete
no tienen una alternativa confiable.Respuestas:
Puede usar
-path
para hacer coincidir una profundidad dada y podar allí. P.ejsería maxdepth 1, ya que
*
coincide con.
,*/*
coincide./dir1
y*/*/*
coincide./dir1/dir2
que se poda. Si usa un directorio de inicio absoluto, también debe agregar un líder/
al-path
.fuente
/*
final del patrón, eliminar el-o
operador y obtener el mismo resultado?*
coincide/
también, por lo que el directorioa/b/c/d/e
encajaría-path */*
, lamentablemente.a/b/c/d/e
nunca se alcanzaría , porque-prune
se aplicaría aa/b
...-prune
y me-o
eliminaron. Si mantiene el-prune
problema, el problema es que*/*
no coincidirá con nada en un nivel superior a la profundidad máxima, por ejemplo, el directorio únicoa
.El enfoque de @meuh es ineficiente ya que su
-maxdepth 1
enfoque todavía permitefind
leer el contenido de los directorios en el nivel 1 para luego ignorarlos de lo contrario. Tampoco funcionará correctamente con algunasfind
implementaciones (incluida GNUfind
) 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).es la forma más canónica de implementar GNU
-maxdepth 1
(o FreeBSD-depth -2
).En general, es lo
-depth 1
que quieres (-mindepth 1 -maxdepth 1
), ya que no quieres considerarlo.
(profundidad 0), y luego es aún más simple:Porque
-maxdepth 2
eso se convierte en:Y ahí es donde se ejecutan los problemas de caracteres no válidos.
Por ejemplo, si tiene un directorio llamado
Stéphane
pero 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 algunasfind
implementaciones) no coincidirá,Stéphane
ya que*
es 0 o más caracteres y 0xe9 no es un carácter.Mi
find
(cuando la salida va a una terminal) muestra ese byte 0xe9 inválido como el?
anterior. Puedes ver queSt<0xe9>phane/Chazelas
no fueprune
d.Puede solucionarlo haciendo:
Pero tenga en cuenta que eso afecta a toda la configuración regional
find
y a cualquier aplicación que ejecute (como a través de los-exec
predicados).Ahora, realmente obtengo un mensaje,
-maxdepth 2
pero 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:para
-mindepth 1 -maxdepth 1
o:para
-maxdepth 2
.Todavía haría un:
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 contenga
find
argumentos demasiado largos , pero también que evite el hecho de que no puede admitir argumentos de ruta arbitraria (excepto-f
con FreeBSDfind
) ya que se ahogará valores de me$dir
gusta!
o-print
...En
-o
combinación con la negación es un truco común para ejecutar dos conjuntos independientes de-condition
/-action
infind
.Si desea ejecutar
-action1
en reunión de archivos-condition1
e independientemente-action2
en reunión de archivos-condition2
, no puede hacer:Como
-action2
solo se ejecutaría para archivos que cumplan ambas condiciones.Ni:
Como
-action2
no se ejecutaría para archivos que cumplan ambas condiciones.funciona como
\( ! -condition1 -o -action1 \)
se resolvería a verdadero para cada archivo. Eso supone que-action1
es 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 -something
donde-something
es inofensivo pero devuelve cierto como-true
en GNUfind
o-links +0
o-name '*'
(aunque tenga en cuenta la cuestión acerca de caracteres no válidos anteriores).fuente
Me encontré con un problema en el que necesitaba una forma de limitar la profundidad al buscar múltiples rutas (en lugar de solo
.
).Por ejemplo:
Esto me llevó a un enfoque alternativo usando -regex. La esencia es:
Entonces, lo anterior sería:
Sin un nombre de archivo:
Finalmente, para
-maxdepth 2
la expresión regular cambia a:'(dir1|dir2)/([^/]*/){0,1}[^/]*$'
fuente
-maxdepth
funcionaría con múltiples rutas de búsqueda.