Pode ser melhor fazer isso com find
:
find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
Gostaria de listar todos os arquivos em uma pasta chamada foldername
com a extensão test
, atest
ou btest
.
Meu pensamento imediato foi executar ls ./foldername/*.{a,b,}test
Isso funciona bem, a menos que não haja nada com a extensão atest
; nesse caso, recebo o erro zsh: no matches found: ./foldername/*.atest
.
Existe alguma maneira de simplesmente ignorar esse erro e imprimir os arquivos que existem?
Eu preciso disso para trabalhar tanto no ZSH quanto no BASH.
Em
ls -d ./foldername/*.{a,b,}test
{a,b,...}
não é um operador glob, que é a expansão de chave, expandida primeiro para:
ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test
E cada glob expandido individualmente e se qualquer glob não corresponder, o comando é cancelado como seria de esperar em zsh
(ou fish
; em bash
, você precisa da opção failglob
para obter um comportamento semelhante).
Aqui, você deseja usar um único glob que corresponda a todos esses arquivos e cancelar o comando apenas se esse glob não corresponder a nenhum arquivo:
ls -d ./foldername/*.(a|b|)test
Você não deseja usar nullglob
, como se nenhum dos globs correspondesse, ele executaria ls
sem argumentos, portanto, liste o diretório atual. cshnullglob
é melhor a esse respeito, pois remove globs não correspondentes, mas ainda cancela o comando se todos os globs não corresponderem.
Você não gostaria de usar nonomatch
, pois isso daria a você o comportamento quebrado de bash
, o que seria uma vergonha.
Para uma alternativa glob que funcione em zsh
e bash
, você pode usar os ksh globs ( set -o kshglob
em zsh
e shopt -s extglob
em bash
).
Então, você faria:
ls -d ./foldername/*.@(a|b|)test
ou:
ls -d ./foldername/*.?([ab])test
Adicione a opção failglob
em bash
para evitar que a glob seja passada literalmente para ls
quando ela não corresponder.
Veja Por que o nullglob não é padrão? para mais informações.
Tags bash ls zsh wildcards shell-script