¿Lista de archivos que coinciden con un patrón pero ignora los archivos que coinciden con otro patrón?

12

Digamos que tengo un directorio con archivos a1, a2, a3, b1, b2, b3. Solo quiero hacer coincidir los archivos que comienzan con apero no contienen 3. Lo intenté ls -I "*3" *a*pero vuelve a1 a2 a3, aunque no quiero que coincida a3. ¿Es esto posible con ls?

Steven
fuente
interesante conjunto diverso de respuestas aquí, pero una explicación de por qué ls -I '* 3' a * falla sería edificante. y / o ¿por qué la lista global de shell no se filtra posteriormente por el interruptor de ignorar a ls?
Theophrastus
La página del manual dice acerca de la opción -I: do not list implied entries matching shell PATTERNsin embargo, no explica qué se entiende por implícito , pero supongo que solo se aplica a los archivos que se lsobtienen mediante expansiones globales, y lsno expande el a*, el shell hace eso .
Murray Jensen

Respuestas:

14

Sólo:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob activa el globbing extendido.
  • a coincide con el inicio a
  • !()niega el partido dentro del ()...
    • *3*que es 3y cualquier cosa antes o después.

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2
caos
fuente
1
FYI, requiereset -s extglob
Brian
@Brian Yea, acabo de notar ^^
caos
8

Las respuestas existentes indican bien la mejor manera de hacer esto con globs; Incluiré esto porque en la mayoría de los casos, findes una mejor opción si desea realizar secuencias de comandos o procesamiento adicional:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

Puede alimentar la respuesta xargspara acciones fáciles, o un while readbucle para cosas más complicadas.

Tom Hunt
fuente
4

Una manera fácil es

  • para enumerar todos los archivos que coinciden a*
  • luego elimine todas las líneas que contengan un 3

El comando UNIX es

ls -1 a* | grep -v 3

ls -1 muestra un archivo por línea.

grepnormalmente encuentra líneas que coinciden con un patrón pero con -veste comportamiento se invierte, es decir, grep encuentra líneas que no coinciden con ese patrón.

Peter K
fuente
2
¡Hola Pedro! Sería mejor explicar, con tantos detalles como sea relevante, cómo funciona su solución.
dhag
2
El análisis lsno es una idea tonta: mywiki.wooledge.org/ParsingLs
caos
3

Con zsh, utilizando el ~ operador global :

setopt extendedglob
print -rl -- a*~*3*

Con gnu lsusted podría usar dos --ignoreopciones:

ls -I '[^a]*' -I '*3*'

el primero ignora todos los nombres de archivo que no comienzan ay el segundo ignora los nombres de archivo que contienen3

don_crissti
fuente