Existem muitas situações em que o uso de a *
é praticamente inevitável - por exemplo, rm -rf *
em uma pasta que contém milhares de subpastas e arquivos.
Mas e se você quiser excluir apenas um ou dois arquivos ou pastas do rm
comando? Pesquisei no Google e só encontrei soluções bastante complicadas, como find . -depth -not \( -name 'one' -o -name 'two' \
-o -name 'three' \) -exec rm {} \;
as mencionadas aqui .
Existe a possibilidade de fazer isso de uma maneira mais fácil - sem esse desvio find
? Por exemplo, rm -rf --exclude='one' --exclude='two' --exclude='three' *
como no rsync ou apenas rm -rf -e 'one','two','three' *
?
Talvez até mesmo uma possibilidade geral de excluir coisas de *
(para que outros comandos como cp
, mv
... não tem que implementar a sua própria)? Algo mais *{'one','two','three'}
ou menos?
fonte
find
com a--delete
opção (não é necessário executarrm
para cada arquivo. Isso é desnecessário).mv -t /tmp one two three && rm -rf * && mv -t . /tmp/one /tmp/two /tmp/three
, mas eu preferiria uma solução que desse a possibilidade de excluir explicitamente algo de*
. Certamente haverá situações em que mover ou copiar os arquivos para outro destino não será uma opção.Respostas:
Para Bash há uma opção de shell chamado
extglob
que está desativada por padrão para manter a compatibilidade com a sintaxe shell padrão. Extglob complementa a sintaxe pelos operadores adicionais, como!()
,?()
,@()
e alguns mais.Para ligar
extglob
, digiteshopt -s extglob
. Para mantê-lo ativado para o tipo de usuário atualecho 'shopt -s extglob' >> ~/.bashrc
.Para o exemplo rm: With
extglob
you can usefonte
shopt
coisa no seu~/.bashrc
, não pode doer.*
, mas adiciona indicadores semelhantes (como o!
) que possuem funções adicionais? Nesse caso, seria uma solução adorável.Criei, exceto exatamente para isso (sry que ainda não consegui adicionar documentação).
Você tem uma pasta como a seguinte:
A digitação
except b d
fornecerá a vocêa
ec
Agora você pode canalizar isso para
rm
.Isso pode ser difícil de lembrar, então por que não criar um script em cima de exceto, chamado
rm-except
:Da mesma forma fácil é
ls-except
:fonte
Como uma alternativa ao extglob (embora essa seja uma resposta muito boa e todos devam ter
shopt -s extglob globstar
em seu .bashrc), você pode usar a variável global $ GLOBIGNORE . Digamos que você deseja obter todos os arquivos, exceto 'foo.txt' e 'bar baz.txt':... no entanto, isso ativará a opção shell
dotglob
, o que significa que*
corresponderá aos arquivos que começam com um ponto (que normalmente estão ocultos). Então você realmente precisa de dois comandos:Como essa é uma variável global, ela afetará todos os globos que você usar até que $ GLOBSTAR seja desmarcado, efetuando logout ou com
Também funcionará apenas nas cadeias literais passadas para a variável. Você pode entender o que quero dizer definindo $ GLOBIGNORE e observando a diferença entre estes comandos:
fonte