Trabalhando de rm / ls com [0-9]

4

Estou aprendendo os comandos shell e me deparei com as tags curtas, por exemplo, [0-9], [[: digit:]] etc. Como prova de conceito, tentei excluir todos os arquivos com o comando rm (i sei que não é uma boa prática, mas eu estou tentando entender como as coisas funcionam), como este

rm [0-9].txt

havia dois arquivos no diretório 0.txt e 9.txt e ele excluía os arquivos 0.txt e 9.txt. Adivinhei que a expressão [0-9] é expandida e, em seguida, lida como 0.txt 1 .txt 2.txt .... No entanto, quando você tenta apenas rm 5.txt, e o arquivo não existe, um erro é lançado ..

alguém por favor me diga como os comandos abreviados funcionam quando usados com rm ou ls.

    
por Works On Mine 23.03.2013 / 22:26

2 respostas

5

Isso se chama globbing (link para a documentação do bash, mas isso não é específico para o bash).

Quando você executou rm [0-9].txt , o shell expandiu [0-9].txt para a lista de arquivos presentes no diretório que correspondia a esse padrão. Em seguida, essa lista é passada como um argumento para rm (cada arquivo como um argumento separado). Então, não, o shell não expandiu para 0.txt 1.txt ... 9.txt , ele olha para os arquivos que combinaram.

Por que você executa apenas rm 5.txt , não há padrão glob para expandir, então o argumento é passado como é para rm , que percebe que o arquivo não existe e reclama.

Tente outra coisa: o mesmo comando rm [0-9].txt , mas em um diretório que não tenha nenhum arquivo que corresponda ao padrão. Você notará rm reclamando novamente, mas desta vez ele dirá:

rm: cannot remove '[0-9].txt': No such file or directory

Isso é o que acontece (por padrão, de qualquer maneira) se um padrão glob não corresponder a nada: o shell não expande e deixa intocado.

Referência POSIX para esse tipo de correspondência de padrões: Notação de correspondência de padrões .

    
por 23.03.2013 / 22:36
5

Não teste com rm , teste com echo !

[0-9].txt é um padrão curinga (também chamado de glob). Ele se expande para uma lista de nomes de arquivos existentes. Em um padrão glob, você pode usar três tipos de curingas:

  • O caractere * corresponde a qualquer sequência de caracteres (incluindo a sequência vazia).
  • O caractere ? corresponde a qualquer caractere.
  • A expressão de colchete […] corresponde a qualquer caractere que aparece entre colchetes.
    [0-9] é um atalho para [0123456789] . Você pode usar um - entre dois caracteres dentro de colchetes para significar esses dois caracteres e quaisquer dois caracteres intermediários. Por exemplo, [0-9a-z_] corresponde a um dígito ou uma letra minúscula ou um sublinhado.
    Existem mais algumas regras sobre colchetes que não mencionarei aqui.

Para reiterar, todas essas construções correspondem apenas aos arquivos existentes. [0-9].txt não será expandido para 5.txt se não houver arquivo com esse nome, mais do que *.txt seria expandido para dfiojedfoi.txt se não houver arquivo com esse nome.

Exemplo:

$ ls
0.txt  10.txt  1a.txt  9.txt  hello.txt  world.txt
$ echo [0-9].txt
0.txt 9.txt
$ echo [0-9][0-9].txt
10.txt
$ echo [0-9][0-9][0-9].txt
[0-9][0-9][0-9].txt
$ echo [0-9]?.txt
1a.txt 10.txt
$ echo [10-19].txt
0.txt 9.txt
$ echo *.txt
0.txt 1a.txt 9.txt 10.txt hello.txt world.txt
$ echo *l*
hello.txt world.txt

echo [0-9][0-9][0-9].txt apenas repete o padrão porque não há arquivo correspondente. Certifique-se de entender por que [10-19].txt corresponde apenas a esses dois arquivos, e não 10.txt ou 19.txt .

    
por 23.03.2013 / 22:44