O que significa [co] no comando “rm -rf filename [co]”?

16

Digamos que tenho dois arquivos em /tmp:

root@ubuntu:~# touch /tmp/hello.{pyc,py}

root@ubuntu:~# ls /tmp/
hello.py  hello.pyc

Agora, vamos executar o rm -rfcomando com a opção [co]

root@ubuntu:~# rm -rf /tmp/hello.py[co]

root@ubuntu:~# ls /tmp/
hello.py

Alguém por favor pode explicar o que está acontecendo aqui? Qual é o [co]parâmetro? Como podemos fazê-lo funcionar para outras extensões? Digamos que eu possua foo.jse foo.coffeearquivos, podemos fazer algo como rm -rf /tmp/foo.coffe[co]excluir o /tmp/foo.js?

aneeshep
fonte
8
Não há necessidade -rfdisso, pois esses não são diretórios ( --recursive) nem graváveis ​​( --force).
Deltab
13
Não há necessidade -rfe não há necessidade de fazer as coisas como raiz. Especialmente se as coisas em questão envolverem rm -rf.
terdon
Gente, são apenas exemplos de comandos para explicar o problema. A questão real era sobre [co]shell glob. Obrigado.
22416 aneeshep
8
@aneeshep Se alguém está olhando para o cano de uma arma e perguntando como limpá-la, primeiro avisa-o sobre olhar para o cano ou diz-lhe como limpá-la?
Duncan X Simpson

Respostas:

34

[co]não é um parâmetro para o rmcomando - é um shell glob que corresponde a um padrão igual a um único caractere do conjunto [co]- em outras palavras, corresponde a cou oa ao final do nome do arquivo. De man bash:

[...]  Matches any one of the enclosed characters

Para corresponder a ambos foo.coffeee foo.js, como os sufixos não contêm substrings comuns, o melhor que você pode fazer é o foo.*que corresponderia a qualquer nome de arquivo começando com foo.Em vez disso, você poderia usar a expansão de chaves, por exemplo

rm foo.{coffee,js}
chave de aço
fonte
Sim entendi. Eu perdi o conceito básico no bash;). Obrigado :)
aneeshep
7
padrões de pesquisa como [abc]ou *vai procurar arquivos enquanto {}não. vá para / tmp, digite e echo nya[ab]; echo nya{a,b}, em seguida, touch nyaanovamenteecho nya[ab]; echo nya{a,b}
Sanya_Zol
16

Não é um parâmetro, mas uma coleção de letras (ou um "shell glob"). Esse é o mesmo:

rm -rf /tmp/hello.py[co]

é o mesmo que

rm -rf /tmp/hello.pyc
rm -rf /tmp/hello.pyo

Semelhante ...

rm -rf /tmp/hello.py[c-o]

excluiria qualquer coisa, /tmp/hello.pycincluindo as /tmp/hello.pyoseguintes ordens ASCII.

rm -rf /tmp/hello.py[ab][cd]

removeria ...

rm -rf /tmp/hello.pyac
rm -rf /tmp/hello.pyad
rm -rf /tmp/hello.pybc
rm -rf /tmp/hello.pybd

digamos, eu tenho os arquivos foo.js e foo.coffee, podemos fazer algo como rm -rf /tmp/foo.coffe[co]excluir o arquivo /tmp/foo.js.

Você pode criar métodos bastante sofisticados, mas para esses 2 arquivos eu os removeria com 1 comando para cada um. Outro exemplo, chegando o mais próximo possível desses 2 arquivos ...

rm /tmp/foo.[cj]*

removeria arquivos como este ...

rm /tmp/foo.c*
rm /tmp/foo.j*

portanto, incluiria muito mais do que apenas esses dois arquivos.

Rinzwind
fonte
2
Se não estou entendendo mal, você recebe uma invocação de rm -rftodas as correspondências, poucas invocações cada uma com uma correspondência.
11
sim. mas não a intenção da empresa que eu adicionei. esses são apenas para mostrar o que seria necessário para ser digitado como um ;-) equivalente
Rinzwind
1

É um shell glob, semelhante aos curingas *e ?... no bash, o padrão de nome de arquivo *.[co]corresponde a todos os nomes de arquivos que terminam com .cou .o.

A diferença com *.[co]versus *.c *.oou *.{c,o}é que os dois últimos padrões serão expandidos para um modelo, *.ose não houver .oarquivos no diretório, enquanto a *.[co]versão não.

Os globs do shell são úteis para executar operações de arquivo de maneira que não diferenciam maiúsculas de minúsculas. Por exemplo, se você tem um monte de arquivos com nomes de arquivos que terminam com jpg, JPG, Jpg, JPg, etc ... e você deseja remover todos eles, você pode fazer:

rm *.[Jj][Pp][Gg]
delt
fonte