Ignora "no coincide"

8

Me gustaría enumerar todos los archivos en una carpeta llamada foldernameque tienen la extensión test, atesto btest.

Mi pensamiento inmediato fue correr ls ./foldername/*.{a,b,}test

Esto funciona bien a menos que no haya nada con la extensión atest, en cuyo caso obtengo el error zsh: no matches found: ./foldername/*.atest.

¿Hay alguna manera de que simplemente pueda ignorar este error e imprimir los archivos que existen?

Necesito que esto funcione tanto en ZSH como en BASH.

Jonathan Hodgson
fuente
3
Redirigir error estándar a /dev/null?
DopeGhoti

Respuestas:

9

Puede ser mejor hacer esto con find:

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
John Moon
fuente
1
quizás con una -maxdepth 1, para emular más de cerca el lscomportamiento
Jeff Schaller
44
@JeffSchaller, tenga en cuenta que -maxdepthes una extensión de GNU. Tenga en cuenta otras 3 diferencias con globs: findincluiría archivos ocultos, no ordenaría la lista y no coincidiría con los nombres de archivo que contienen bytes que no forman caracteres válidos (como un $'St\xe9phane.atest'en una ubicación UTF-8)
Stéphane Chazelas
11

En

ls -d ./foldername/*.{a,b,}test

{a,b,...} no es un operador global, eso es expansión de llaves, primero se expande para:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

Y cada globo se expandió individualmente, y si algún globo no coincide, el comando se cancela como es de esperar en zsh(o fish; en bash, necesita la failglobopción de obtener un comportamiento similar).

Aquí, querrás usar un único globo que coincida con todos esos archivos, y solo cancelar el comando si ese globo no coincide con ningún archivo:

ls -d ./foldername/*.(a|b|)test

No desea utilizarlo nullglob, ya que si ninguno de los globs coincidiera, se ejecutaría lssin argumentos, así que enumere el directorio actual. cshnullglobes mejor en ese sentido, ya que elimina los globos que no coinciden pero aún cancela el comando si todos los globos no coinciden.

No querrás usarlo nonomatch, ya que eso te daría un comportamiento roto, lo bashcual sería una pena.

Para una alternativa glob que funcione en ambos zshy bash, puede usar los globos ksh ( set -o kshglobin zshy shopt -s extglobin bash).

Entonces, harías:

ls -d ./foldername/*.@(a|b|)test

o:

ls -d ./foldername/*.?([ab])test

Agregue la failglobopción bashpara evitar que el glob se pase literalmente a lscuando no coincida.

Consulte ¿Por qué nullglob no es el predeterminado? para más información.

Stéphane Chazelas
fuente
No estoy seguro de por qué es un requisito del OP, pero ¿existe un extglob que funcione para esto en bash y zsh? Tuve que usar ?(...)o +(...)para bash.
Jeff Schaller
@JeffSchaller, ver edición
Stéphane Chazelas