¿Cómo excluir / ignorar archivos y directorios ocultos en una búsqueda de "búsqueda" incrustada con comodines?

119

A partir de (observe los comodines antes y después de "algún texto")

find . -type f -name '*some text*'

¿Cómo se puede excluir / ignorar todos los archivos y directorios ocultos?

Ya he estado buscando en Google durante demasiado tiempo , encontré algo de ciruela y! (signo de exclamación) parámetros, pero no hay un ejemplo apropiado (y parsimonioso) que simplemente funcionó .

Tubería | a grepsería una opción y también agradecería ejemplos de eso; pero principalmente estoy interesado en una breve línea (o un par de líneas independientes, que ilustran diferentes formas de lograr el mismo objetivo de línea de comandos) simplemente usando find.

ps: Buscar archivos en Linux y excluir directorios específicos parece estar estrechamente relacionado, pero a) aún no se acepta yb) está relacionado pero es diferente y distinto, pero c) puede proporcionar inspiración y ayudar a identificar la confusión.

Editar

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", trabajos. La expresión regular busca "cualquier cosa, luego una barra diagonal, luego un punto, luego cualquier cosa" (es decir, todos los archivos y carpetas ocultos, incluidas sus subcarpetas), y el "!" niega la expresión regular.

loco por natty
fuente
No ayuda con lo que pidió en su edición, pero eche un vistazo a mi pregunta y su respuesta aquí: unix.stackexchange.com/q/69164/15760 y también el enlace en la respuesta.

Respuestas:

134

Esto imprime todos los archivos que son descendientes de su directorio, omitiendo los archivos y directorios ocultos:

find . -not -path '*/\.*'

Entonces, si está buscando un archivo con some textsu nombre y desea omitir archivos y directorios ocultos, ejecute:

find . -not -path '*/\.*' -type f -name '*some text*'

Explicación:

La -pathopción se ejecuta comprueba un patrón contra toda la cadena de ruta. *es un comodín, /es un separador de directorio, \.es un punto (se debe escapar para evitar un significado especial) y *es otro comodín. -notsignifica no seleccionar archivos que coincidan con esta prueba.

No creo que findsea ​​lo suficientemente inteligente como para evitar la búsqueda recursiva de directorios ocultos en el comando anterior, así que si necesita velocidad, use -pruneen su lugar, así:

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print
Flimm
fuente
¡Tenga en cuenta con el último que lo necesita -printal final! Además, no estoy seguro de si -name '\.*' would be more efficient instead of -path` (porque la ruta está buscando subrutas, pero se eliminarán)
artfulrobot
¿Cuál es el significado especial de .en este contexto?
frostschutz
@frostschutz El punto siguiente findsignifica el directorio actual: findexaminará todos los archivos y directorios en el directorio actual. El argumento posterior pathes una expresión regular, donde un punto normalmente significaría "cualquier carácter", para que signifique un punto literal, tenemos que escapar con una barra diagonal inversa. El argumento posterior -name no es una expresión regular, pero expande comodines como ?y *como lo hace un shell.
Flimm
2
@frostschutz En realidad, ahora que lo pienso, puedo estar equivocado acerca de .tener un significado especial.
Flimm
1
@Flimm sí, no hay necesidad de escapar .. Por lo que yo sé, sólo éstos tienen que ser escapado: *, ?, y [].
thdoan
10

Este es uno de los pocos medios para excluir archivos de puntos que también funcionan correctamente en BSD, Mac y Linux:

find "$PWD" -name ".*" -prune -o -print
  • $PWD imprime la ruta completa al directorio actual para que la ruta no comience con ./
  • -name ".*" -prune coincide con cualquier archivo o directorio que comience con un punto y luego no descienda
  • -o -printsignifica imprimir el nombre del archivo si la expresión anterior no coincide con nada. Usar -printo -print0hace que todas las demás expresiones no se impriman de manera predeterminada.
eradman
fuente
Por favor explique / explique sobre "alarmantemente complicado"; las respuestas ya dadas y su respuesta parecen dar evidencia de lo contrario ...?
loco sobre natty
2
"alarmantemente complicado" es probablemente excesivo. Reescribí la respuesta para ir al grano. Creo que la respuesta que publiqué es difícil de entender y es difícil de ver sin una lectura muy cuidadosa de la página del manual. Si solo está utilizando GNU find, entonces hay más soluciones posibles.
eradman
-o ... -printes útil. Para mi uso, ahora tengo find ... '!' -name . -name '.*' -prune -o ... -print, que era más conveniente que incluir $ PWD.
Roger Pate
4
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

Excluye todos los directorios ocultos y archivos ocultos bajo $ DIR

huésped
fuente
Esta es la respuesta perfecta. Encuentra recursivamente todos los archivos pero excluye las líneas de pedido de directorios y archivos ocultos. ¡Gracias!
KyleFarris
2

La respuesta que publiqué originalmente como una "edición" a mi pregunta original anterior:

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", trabajos. La expresión regular busca "cualquier cosa, luego una barra diagonal, luego un punto, luego cualquier cosa" (es decir, todos los archivos y carpetas ocultos, incluidas sus subcarpetas), y el "!" niega la expresión regular.

loco por natty
fuente
Similar, pero solo para la carpeta actual:find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
phyatt
2

No tienes que usar findpara eso. Solo usa globstar en shell, como:

echo **/*foo*

o:

ls **/*foo*

donde **/representa cualquier carpeta recursivamente y *foo*cualquier archivo que tenga fooen su nombre.

De forma predeterminada, el uso lsimprimirá los nombres de los archivos, excepto los archivos y directorios ocultos.

Si no tiene habilitado el globbing, hágalo shopt -s globstar.

Nota: Una nueva opción de globbing funciona en Bash 4, zsh y shells similares.


Ejemplo:

$ mkdir -vp a/b/c/d
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
mkdir: created directory 'a/b/c/d'
$ touch a/b/c/d/foo a/b/c/d/bar  a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden
$ echo **/*foo*
a/b/c/d/foo  a/b/c/d/foo_not_hidden
kenorb
fuente
55
¡No necesitas lspara eso! echo **/*foo*
Kevin Cox
@kenorb (y @ kevin-cox). ¿Podrías ser un poco más detallado? ¿Por qué Globstar (= *) funciona aquí y cómo? ¿Qué hace la barra / hacer?
loco por natty
@nuttyaboutnatty /significa carpeta, separa los directorios del nombre del archivo. *Básicamente representa todo.
kenorb
@kenorb sí, pero: ¿cómo ayuda esa frase con la pregunta original?
loco por natty
1
@nuttyaboutnatty Ejemplo aclarado y agregado. Ayuda al encontrar archivos que ignoran el oculto.
kenorb
1

La respuesta de @ Flimm es buena, particularmente porque evita que la búsqueda descienda a directorios ocultos . Prefiero esta simplificación:

Generalmente para excluir todas las rutas ocultas (archivos normales, directorios, etc.):

find <start-point> -path '*/.*' -prune -o <expression> -print

Por ejemplo, usando su directorio de trabajo como punto de inicio y -name '*some text*'como expresión:

find . -path '*/.*' -prune -o -name '*some text*' -print

En contraste con lo que sugiere la respuesta de @ Flimm, no hay archivos ocultos o directorios ocultos es el caso simple. La -path '*/.*'expresión es cierto para cualquier camino (archivos regulares, directorios, etc.) que tiene una .inmediatamente después de su separador de archivos, /. Entonces, esta línea eliminará los archivos y directorios ocultos.

Permitir archivos ocultos y excluir directorios ocultos es el caso que requiere un filtro adicional. Aquí es donde incluirías -type den la expresión que se está podando.

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

Por ejemplo:

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

En este caso -type d -path '*/.*'es truesolo para directorios, por lo que solo se eliminan los directorios.

De Novo
fuente
0

findtiene interruptores lógicos limpios como -andy -notpuede usarlos a su favor para encontrar un archivo coincidente con dos reglas como esta:

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 

$ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            
./non_hidden_file.txt

Como puede ver, findusa dos reglas -name '*hidden_file*'y -and \( -not -name ".*" \)para encontrar los nombres de archivo que coinciden con ambas condiciones: nombre de archivo con hidden_fileél pero sin punto inicial. Tenga en cuenta las barras delante del paréntesis: se utilizan para definir paréntesis como findargumentos en lugar de definir una subshell (que es lo que significa paréntesis de lo contrario sin barras)

Sergiy Kolodyazhnyy
fuente
0
$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

Notas:

  • . : carpeta actual
  • eliminar -maxdepth 1para buscar de forma recursiva
  • -type f: buscar archivos, no directorios ( d)
  • -not -path '*/\.*' : no volver .hidden_files
  • sed 's/^\.\///g': elimina el antepuesto ./de la lista de resultados
Victoria Stuart
fuente