No linux, como excluir todos os arquivos, EXCETO o padrão * .txt?

74

Eu sei como excluir todos os txtarquivos no diretório atual por rm *.txt. Alguém sabe como excluir todos os arquivos no txtarquivo EXCEPT do diretório atual ?

Arma de fogo
fonte
21
Como sempre, teste as respostas fornecidas com um comando inofensivo, como lsantes de realmente tentar ligar rm.
chepner
^ Esse cara não gosta de viver perigosamente .. :)
jDub9

Respostas:

111

Você pode usar find:

find . -type f ! -name '*.txt' -delete

Ou os recursos de globbing estendidos do bash:

shopt -s extglob
rm *.!(txt)

Ou no zsh:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything
Kevin
fonte
Alguns deles podem precisar ser adaptados, dependendo se você possui pastas e o que deseja fazer com elas.
Kevin
11
Não deveria *.!(txt)ser !(*.txt)?
Lri
O @LauriRanta depende do conteúdo da pasta, para o qual não recebemos resposta. Tudo bem, como se todos os arquivos tivessem extensões, e rmsufocariam se houvesse pastas.
Kevin
Eu tenho um problema com os colchetes. Quando uso o estilo globbing em um script bash, ele reclama de um erro de sintaxe e de parênteses. No entanto, fazê-lo a partir da CLI funciona.
precisa saber é o seguinte
11
@izogfif verifique se isso find . -type f ! -name "*.txt" | xargs -r rmfuncionaria no GNU \ xargs. Comando BSD e UNIX xargs podem não ter -r você tem que verificar o seu local deman xargs
Ntwobike
10

existem muitas maneiras de fazer isso. mas a maneira mais simples seria (bash):

shopt -s extglob
rm !(*.txt)
Kent
fonte
10

Se você quiser excluir todos os arquivos, exceto '* .txt', poderá usar o seguinte comando:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

mas se você também quiser excluir diretórios junto com os arquivos, poderá usar o seguinte:

$ find . ! -name "*.txt" -exec rm -r {} \;

Sagar Rakshe
fonte
4

Uma solução sem find:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

Isso deve funcionar em todos os tipos de conchas.

michas
fonte
3

Você pode usar grep e xargs invertidos

ls | grep -v .txt$| xargs rm
rjv
fonte
ls | grep -v *.txt | xargs rmfunciona da mesma maneira #
phillipsk
O @phillipsk grep -v *.txtfuncionará apenas se houver exatamente um .txtarquivo. Se não houver, grepserá usado *.txtcomo padrão; se houver mais de um, ele procurará o primeiro nome do arquivo dentro de todos os outros .txtarquivos, ignorando a saída de ls. (Resultados exactos podem depender de opções glob do shell.)
JigglyNaga
.txt$corresponderá as strings que terminam com txtindependentemente do ponto. Porque grepusa expressão regular como parâmetro. Assim, arquivos a.txte aatxte a-txttudo vai ser acompanhado por esta expressão. Expressão correta deve ser ls | grep -v \\.txt$ | xargs --no-run-if-empty rm. Para pessoas curiosas: se você quiser brincar com a expressão, use com segurança essa expressão de teste ls | grep \\.txt$ | xargs --no-run-if-empty echo(nota: não há -vsinalizador e rm=>echo). Nota 2: você pode ter notado uma barra invertida dupla. Um é para regex, outro é para que o bash escape da barra.
precisa
1

Simplesmente faça:

rm $(ls -I "*.txt" ) # Exclui o tipo de arquivo, exceto * .txt

Da mesma forma, se for necessário excluir "exceto um ou mais tipos de arquivo", faça:

rm $(ls -I "*.txt" -I "*.pdf" ) # Exclui tipos de arquivo, exceto * .txt e * .pdf

Surya
fonte
Bem-vindo ao StackExchange! A -Iopção pode ser útil, mas veja por que não analisar ls . E o que isso | xargsalcança? Sem argumentos, ele roda echoem todas as suas entradas.
precisa saber é o seguinte
O que é xargssuposto alcançar?
dhag 21/07
Obrigado, xargs não foi útil no caso acima, foi corrigido agora.
Surya
0

Isso também funciona para remover todos os arquivos e pastas ocultos (pontos), exceto o indicado ( .mydir):

rm -rf $(ls -aI ".mydir")
Chetabahana
fonte