2011-12-15 12 views
46

Así es como se puede listar todos los archivos que coinciden con un patrón en bash:¿Los archivos de la lista no coinciden con un patrón?

ls *.jar 

Cómo enumerar el complemento de un patrón? es decir, todos los archivos no coinciden * .jar?

+0

esto probablemente no debería etiquetarse como regex, * es un comodín comodín y no es una expresión regular *, que es el "cero o más cuantificador". – sweaver2112

+0

Buen punto, aunque estoy aprendiendo que usar expresiones regulares es probablemente una mejor práctica para obtener las coincidencias que esperas. – paislee

Respuesta

38
ls | grep -v '\.jar$' 

por ejemplo.

+2

¿Qué es -v flag para grep? – paislee

+12

partido invertido. También hay un 'man grep'. –

+0

¿Cómo se pueden hacer dos tipos de archivos? – Dan

2

Una solución sería ls -1|grep -v '\.jar$'

+0

[No analizar el resultado de 'ls'] (http://mywiki.wooledge.org/ParsingLs), gracias. –

+6

@gniourf_gniourf no seas religioso acerca de reglas como analizar 'ls' o usar' goto'. Algunas veces esas soluciones funcionan mejor. –

+1

Este no es uno de esos casos; 'encontrar. -print0 | grep -z '\ .jar $' 'funciona mejor incluso si no quieres usar' -ignore' o el globbing extendido de Bash. Dicho esto, la mayoría de la gente no quiere leer un artículo entero para entender una regla o lo que deben * * hacer, y se puede ajustar una explicación simple y recomendación como “no funciona en casos extremos; use 'find -print0' y' grep -z' en su lugar "en un comentario. –

13

Con una versión adecuada de find, se podría hacer algo como esto, pero es un poco exagerado:

find . -maxdepth 1 ! -name '*.jar' 

find encuentra archivos. El argumento . especifica que desea comenzar a buscar desde ., es decir, el directorio actual. -maxdepth 1 le dice que solo desea buscar un nivel profundo, es decir, el directorio actual. ! -name '*.jar' busca todos los archivos que no coinciden con la expresión regular *.jar.

Como dije, es un poco exagerado para esta aplicación, pero si elimina el -maxdepth 1, puede buscar recursivamente todos los archivos que no sean jar o lo que tenga fácilmente.

27

poco conocida regla de expansión bash:

ls !(*.jar) 
+2

bash:!: Evento no encontrado. ¿Qué necesito? – paislee

+6

Intenta ejecutar 'shopt -s extglob' en la línea de comando primero, luego escribe el comando. –

58

Uso de estilo egrep patrón extendido a juego.

ls !(*.jar) 

Esto está disponible comenzando con bash-2.02-alpha1. primero debe estar habilitado con

shopt -s extglob 

A partir de bash-4.1-alfa hay una opción de configuración para habilitar esta manera predeterminada.

+1

¡Yay por mencionar el extglob de tiendas! –

+2

Esta es la respuesta correcta. La respuesta marcada como correcta no usa el shell directamente, usa un comando auxiliar. – dbn

+0

@dbw - Incluso si me gusta más esta respuesta, la respuesta aceptada es correcta para la pregunta. El OP no solicita específicamente el uso de "el caparazón directamente". –

14

POSIX define expresiones de corchetes que no coinciden, por lo que podemos permitir que el shell expanda los nombres de archivo para nosotros.

ls *[!j][!a][!r] 

Esto tiene algunas peculiaridades, pero al menos es compatible con cualquier shell de Unix.

+0

+1 para cumplimiento con POSIX. Una pequeña función bash/python/ruby ​​combinada con alias, es decir. "lsnot" podría hacerlo fácilmente viable. – Nikkolasg

+0

Esto no coincide con elementos de menos de tres caracteres. –

1

Y si desea excluir más de una extensión de archivo, sepárelos con un conducto |, como ls test/!(*.jar|*.bar). Vamos a intentarlo:

$ mkdir test 
$ touch test/1.jar test/1.bar test/1.foo 
$ ls test/!(*.jar|*.bar) 
test/1.foo 

En cuanto a las otras respuestas que pueda necesitar para shopt -s extglob primero.

+1

Puede acortar esto a '! (*. [Bj] ar)' en su lugar. –

Cuestiones relacionadas