Así es como puede especificar eso con find
:
find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"
Explicación:
find .
- Iniciar la búsqueda desde el directorio de trabajo actual (de forma recursiva de forma predeterminada)
-type f
- Especifique find
que solo desea 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 excluir todos los resultados cuya ruta comience con ./scripts/
Prueba de 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, la -name
opción solo considera el nombre de base, donde as -path
considera la ruta completa =)
_peaks.bed
.find
, pero dado que la pregunta está etiquetada como Linux, eso no es un problema. Buena respuesta..
en el indicador de búsqueda inicial, debe usarlo en cada ruta que excluya. La coincidencia de rutas es bastante estricta, no realiza búsquedas difusas. Entonces, si lo usas,find / -type f -name *.bed" ! -path "./tmp/"
no va a funcionar. necesitas tener! -path "/tmp"
que hacerlo feliz.$ ! -path "./directory/*"
-prune
lugar de comprobar todos los archivos del árbol". Si sus directorios excluidos son muy profundos o tienen toneladas de archivos y le importa el rendimiento, utilice la-prune
opción en su lugar.Aquí hay una forma en que puede hacerlo ...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
fuente
find
GNU, y no solo con GNUfind
. Sin embargo, la pregunta está etiquetada como Linux, por lo que no es crítica.Utilizar
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. Evalúa de izquierda a derecha. Comience siempre con la exclusión del camino.
Explicación
No utilice
-not
(o!
) para excluir todo el directorio. Utilice-prune
. Como se explica en el manual:y en el manual de búsqueda de GNU:
De hecho, si usa
-not -path "./pathname"
, find evaluará la expresión para cada nodo debajo"./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 descienda a él.-path "./script" ! -prune
- se evalúa como(-path "./script") AND (! -prune)
. Revierte el "siempre verdadero" de podar a siempre falso. Evita imprimir"./script"
como un partido.-path "./script" -prune -false
- dado que-prune
siempre devuelve verdadero, puede seguirlo con-false
para hacer lo mismo que!
.-o
- Operador OR. 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 buscar; es por eso que la mayoría de las veces, no es necesario agregarlo en su expresión. Y dado que-prune
devuelve verdadero, imprimirá "./script" y "./tmp".No es necesario en los demás porque cambiamos
-prune
para devolver siempre falso.Sugerencia: puede usar
find -D opt expr 2>&1 1>/dev/null
para ver cómo se optimiza y expande,find -D search expr 2>&1 1>/dev/null
para ver qué ruta está marcada.fuente
Prueba algo como
find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -prune \)
y no se sorprenda demasiado si me equivoco un poco. Si el objetivo es un ejecutivo (en lugar de imprimir), simplemente sustitúyalo en su lugar.
fuente
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 de procedimiento de ...
-o - Entonces, si no coincide, imprima los resultados (pode los directorios e imprima 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
fuente
find . -path ./scripts -prune -name '*_peaks.bed' -type f
. No estoy seguro de cómo excluir varios directorios. Esto también enumera el directorio excluido de nivel superior aunquetype
esté especificado. La exclusión a través de Grep parece más sencilla a menos que desee utilizar Prune para acelerar la operación de búsqueda.Puedes probar a continuación:
find ./ ! \( -path ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'
fuente