Eu esperei isso:
$ rm *(1)*
removeria todos os arquivos que contêm (1)o nome. Eu estava errado. Ele removeu todos os arquivos no diretório.
Por quê?
Eu esperei isso:
$ rm *(1)*
removeria todos os arquivos que contêm (1)o nome. Eu estava errado. Ele removeu todos os arquivos no diretório.
Por quê?
Respostas:
De man bash:
*(pattern-list)
Matches zero or more occurrences of the given patterns
Você tem uma expressão glob que corresponde aos arquivos que começam com zero ou mais 1s - que são todos os arquivos.
Uma maneira simples de desativar esse comportamento globbing é \escapar dos parênteses:
rm *\(1\)*
Caso contrário, você pode usar shopt -u extglobpara desativar o comportamento e shopt -s extglobreativá-lo:
shopt -u extglob
rm *(1)*
shopt -s extglob
Observe que, como diz Stephane , extglobé habilitado bash-completiondesabilitando-o, podendo fazer com que as funções de conclusão não funcionem corretamente.
extglobnão está ativado por padrão, mas está ativado por bash_completion se você tiver o instalado e ativado. bashnão tem escopo local para opções como o zshfaz.
bash-4.3há uma regressão que *(1)*também expande arquivos ocultos.
Isso provavelmente está relacionado à extglobopção de shell. Se eu desligá-lo, o padrão produz uma mensagem de erro:
martin@dogmeat:~$ shopt -u extglob
martin@dogmeat:~$ shopt extglob
extglob off
martin@dogmeat:~$ echo *(1)*
bash: syntax error near unexpected token `('
Se eu ligá-lo, parece realmente combinar com tudo. A página de manual documenta esses padrões, acho que eles estão relacionados:
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 fol‐
lowing 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
Não vejo nenhuma documentação que especifique o que os parênteses sem um caractere à esquerda fazem. De qualquer forma, você pode contornar o problema citando os parens:
martin@dogmeat ~ % echo *\(1\)*
A(1)b
Além disso, use echoou lspara testar seu padrão primeiro, se você não tiver certeza absoluta de que está funcionando :)
{é uma chave, (é um parêntese (ou suporte redondo).
{= colchete, (= colchete redondo, [= colchete. Em americano: {= chave, (= paren, [= chave. Um pouco confuso. Se você precisar verificar como algo se chama, Jargon File - ASCII é bastante útil.
{é um suporte de flores, [é um suporte quadrado e (é um suporte redondo ou, mais comumente, apenas um suporte. :-)
rmcom um padrão, sempre o antecedoechoantes de emitir o comando real. O hábito me salvou mais de uma vez (desde então, aos 6 anos de idade, confundindo a diferença entreDEL A: *.*eDEL *.* A:).