GNU/Linux >> Tutoriales Linux >  >> Linux

Use el comando de búsqueda pero excluya archivos en dos directorios

Aquí hay una forma en que podrías hacerlo...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"

para mí, esta solución no funcionó en un comando ejecutivo con find, realmente no sé por qué, así que mi solución es

find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

Explicación: igual que sampson-chen uno con las adiciones de

-prune - ignora la ruta anterior de ...

-o - Luego, si no hay coincidencias, imprime los resultados (elimina los directorios e imprime los resultados restantes)

18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3:    0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4:    0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5:    0.0% -- replaced with ./e/5.gz
./e/a:    0.0% -- replaced with ./e/a.gz
./e/b:    0.0% -- replaced with ./e/b.gz

Así es como puede especificar eso con find :

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

Explicación:

  • find . - Iniciar búsqueda desde el directorio de trabajo actual (recursivamente por defecto)
  • -type f - Especificar a find que solo quieres archivos en los resultados
  • -name "*_peaks.bed" - Busque archivos cuyo nombre termine en _peaks.bed
  • ! -path "./tmp/*" - Excluir todos los resultados cuya ruta comience con ./tmp/
  • ! -path "./scripts/*" - También excluya todos los resultados cuya ruta comience con ./scripts/

Probar la solución:

$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"

./d/4
./c/3
./e/a
./e/b
./e/5

Estuviste bastante cerca, el -name La opción solo considera el nombre base, mientras que -path considera todo el camino =)


Usar

find \( -path "./tmp" -o -path "./scripts" \) -prune -o  -name "*_peaks.bed" -print

o

find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o  -name "*_peaks.bed"

o

find \( -path "./tmp" -path "./scripts" \) ! -prune -o  -name "*_peaks.bed"

El orden es importante. Se evalúa de izquierda a derecha. Siempre comience con la exclusión de la ruta.

Explicación

No use -not (o ! ) para excluir todo el directorio. Utilice -prune .Como se explica en el manual:

−prune    The primary shall always evaluate as  true;  it
          shall  cause  find  not  to descend the current
          pathname if it is a directory.  If  the  −depth
          primary  is specified, the −prune primary shall
          have no effect.

y en el manual de búsqueda de GNU:

-path pattern
              [...]
              To ignore  a  whole
              directory  tree,  use  -prune rather than checking
              every file in the tree.

De hecho, si usa -not -path "./pathname" ,find evaluará la expresión para cada nodo bajo "./pathname" .

Las expresiones de búsqueda son solo evaluación de condiciones.

  • \( \) - operación de grupos (puede usar -path "./tmp" -prune -o -path "./scripts" -prune -o , pero es más detallado).
  • -path "./script" -prune - si -path devuelve verdadero y es un directorio, devuelve verdadero para ese directorio y no descender a él.
  • -path "./script" ! -prune - se evalúa como (-path "./script") AND (! -prune) . Revierte el "siempre verdadero" de ciruela pasa a siempre falso. Evita imprimir "./script" como un partido.
  • -path "./script" -prune -false - desde -prune siempre devuelve verdadero, puedes seguirlo con -false hacer lo mismo que ! .
  • -o - Operador O. Si no se especifica ningún operador entre dos expresiones, el valor predeterminado es el operador AND.

Por lo tanto, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print se expande a:

[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )

La impresión es importante aquí porque sin ella se expande a:

{ [ (-path "./tmp" OR -path "./script" )  AND -prune ]  OR (-name "*_peaks.bed" ) } AND print

-print se agrega mediante find; es por eso que la mayoría de las veces, no necesita agregarlo en su expresión. Y desde -prune devuelve verdadero, imprimirá "./script" y "./tmp".

En los demás no es necesario porque cambiamos -prune para devolver siempre falso.

Pista:puedes usar find -D opt expr 2>&1 1>/dev/null para ver cómo se optimiza y amplía,
find -D search expr 2>&1 1>/dev/null para ver qué ruta está marcada.


Linux
  1. Cómo usar el comando Grep para buscar texto en archivos

  2. Copiar archivos y directorios en Linux

  3. ¿Encontrar archivos o directorios más grandes?

  4. Cómo usar el comando find de Linux para buscar archivos

  5. ¿Cómo encontrar / enumerar todos los archivos únicos en dos directorios?

Comando Grep en Linux (Buscar texto en archivos)

Cómo usar el comando cp para copiar archivos y directorios

Cómo usar el comando SCP para transferir archivos

Cómo excluir un directorio al buscar archivos en Linux

Encuentre archivos y directorios en Linux fácilmente

¿Cómo averiguar los principales directorios o archivos que consumen espacio?