
É bash
possível usar curingas para especificar "todos os arquivos no diretório atual, EXCETO [arquivos que correspondem a um padrão específico (curinga)]"? Por exemplo, "todos os arquivos que não correspondem a *~"
Ou, de maneira mais geral, é possível qualificar uma especificação de arquivo curinga com uma segunda especificação de filtragem ou negação?
Responder1
Claro. Digamos que você queira que todos os arquivos contenham a string "foo" em seus nomes, mas nenhum que também contenha "bar". Então você quer
foo1
foo2
Mas você não quer
foobar1
Você pode usar globbing simples para fazer isso:
for f in foo!(bar)*; echo $f; done
ou então
ls foo[^bar]*
Para mais veja aqui:http://www.tldp.org/LDP/abs/html/globbingref.htmlCuidado, ambos os métodos têm suas armadilhas. Provavelmente é melhor você usar find
.
Responder2
Obrigado bjanssen por apontar o bash extglob shopt
que permite esse tipo de globbing.
Na bash
página de manual:
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the following
sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Então, para responder à minha pergunta "como especificartodos os arquivos que não correspondem *~":
!(*~)
ou, sem a necessidade de extglob
:
*[^~]
E de forma mais geral, respondendo à última parte da minha pergunta:
The GLOBIGNORE shell variable may be used to restrict the set of file names
matching a pattern. If GLOBIGNORE is set, each matching file name that also
matches one of the (colon-separated) patterns in GLOBIGNORE is removed from
the list of matches.