Como canalizo ls para grep e excluo os arquivos filtrados por grep?

33

Eu queria excluir um pacote do meu arquivo inicial, mas o nome do arquivo era muito longo ( google-chrome-stable_current_i386.deb). Então, decidi usar o comando ls|grep chrome|rmpara canalizar os arquivos para grep, filtrar o arquivo chrome e removê-lo. Não funcionou, então eu gostaria de ver como posso fazer isso.

SpecialBomb
fonte
22
rm -i *chrome*.deb
7278 Lambert
28
De um modo geral, não gosto quando as pessoas postam respostas "não faça isso", mas este é um dos melhores exemplos de um problema XY que eu já vi. Sua verdadeira pergunta é "como excluo rapidamente um arquivo com um nome de arquivo longo, sem digitar tudo", e há muitas maneiras boas que não envolvem saudar a saída dels
Michael Mrozek
5
Basta usar find- find . -name "*chrome*" -delete.
Boris the Spider
3
Meus dois centavos como usuário do StackExchange: no futuro, faça sua pergunta de uma maneira mais genérica e forneça detalhes sobre o que você tentou. "Como eu excluo arquivos em uma pasta com uma determinada string no nome do arquivo?" poderia ter sido uma maneira melhor de expressá-lo. Em seguida, você pode simplesmente adicionar, como um aparte, que tentou tubulação lsatravés grepde rm, mas não conseguiu fazê-lo funcionar. Dessa forma, você obterá uma ou duas boas respostas sobre a maneira "correta" ou "mais fácil" de realizar sua tarefa, em vez de forçar alguém a lhe dar uma boa resposta sobre uma solução ineficiente.
Adrian

Respostas:

56

Isso quase me fez estremecer.

  1. Você pode parar de apontar a espingarda ao seu pé. Basicamente, qualquer tipo de análise lsserá mais complicado e propenso a erros do que métodos estabelecidos como find [...] -execou globs .
  2. A menos que alguém tenha instalado uma distro de troll para você, seu shell está Tabcompleto. Basta digitar rm googlee pressionar Tab. Se não for concluído imediatamente, pressione Tabnovamente para ver uma lista dos arquivos correspondentes. Digite mais caracteres do nome do arquivo para reduzi-lo até que seja concluído e execute o comando.
  3. Tubos ! = Parâmetros . A entrada padrão é um fluxo de dados binários que pode ser alimentado a um comando de forma assíncrona. Parâmetros são cadeias separadas por espaço que são passadas uma vez e apenas uma vez para um comando ao executá-lo. Estes são muito raramente intercambiáveis.
l0b0
fonte
11
Desculpe se parecia uma pergunta n00b. Eu sabia que não havia problema em usar geralmente, pois o pacote indicado era o único pacote com "chrome" indicado. Portanto, o uso do grep filtraria apenas um arquivo. Eu sou bastante novo no linux e já fiz muitos scripts bash, mas ainda não sei tudo: P. Duro, cara.
SpecialBomb
5
Não queria ser duro, mas a concha é um ambiente duro e implacável, escondido atrás de uma superfície meio amigável. Fazer as coisas com segurança é bastante difícil, não importa com segurança ou mesmo corretamente .
L0b0 07/12/2015
2
@SpecialBomb Esta é a única resposta correta. Explicar como apontar corretamente a espingarda para cortar o próprio pé, como as outras respostas, certamente não é o caminho a seguir. Seja especialmente cuidadoso ao executar cegamente rm- é provavelmente a maneira mais comum de fritar sua distribuição.
Boris the Spider
@BoristheSpider Heh, eu definitivamente já fritei o Ubuntu duas vezes instalando drivers de placa de vídeo AMD. Eu já fiz uma pergunta sobre isso. A AMD tem sido horrível, então perguntei se havia alguma correção comum ou melhores métodos de jogo com o Linux em uma placa AMD.
SpecialBomb
34

Você também pode usar o comando find com um curinga:

find . -maxdepth 1 -name '*chrome*' -delete

Observe que o argumento "-maxdepth" garante que a localização funcione apenas no diretório atual e não se repita em subdiretórios.

lustre
fonte
11
Sugestões para melhorias: (a) use -inamepara nomes de arquivos que não diferenciam maiúsculas de minúsculas (b) canalize o xargsuso de -print0sinalizador para finde -0sinalizador para xargs. O uso de xargspermite que você faça coisas como fooexclusões "interativas" (confirmar exclusão ?).
Christopher Schultz
3
Não há necessidade de canalizar para xargs se você usar a opção -exec:find . -name '*chrome*' -exec rm -i {} +
Johnny
4
Isso também não será excluído recursivamente em subdiretórios? Você pode precisar especificar maxdeptha ser 1.
Tyzoid
32

Você teve a ideia certa, apenas perdeu alguns detalhes. Como você está lidando com uma lista que chega ao STDIN e rmespera parâmetros, você precisa usá-lo xargs.

Portanto:

ls | grep chrome | xargs rm

Deve dar o que você quer.

Observe que, se você deseja excluir tudo que não seja o chromearquivo, pode simplesmente adicionar -và grepinstrução.

Observe que, de acordo com as outras respostas a essa pergunta, essa provavelmente é uma maneira ruim de realizar o que você deseja realizar.

John
fonte
Com -v, isso não excluiria tudo, exceto os arquivos correspondentes chrome? Eu não acho que é isso que o OP quer ...
akivajgordon
Olhando de novo, você está correto. O OP quer "filtrar o arquivo chrome", mas depois deseja removê-lo.
John
Isso parece desnecessariamente complexa, em comparação com um simples "rm -i cromo "
chander
5
A resposta aceita funciona, mas veja a resposta abaixo, que explica por que é uma má ideia. (Publicação este comentário aqui só por causa daqueles que parar logo que eles vêem uma marca de verificação "aceito".)
Jim Davis
11
Isso, a resposta aceita "funcionará" somente se não houver nomes de arquivos "estranhos" na lssaída. Nomes de arquivos com espaços irão destruir isso. Isso também é perigoso se alguém puder construir um nome de arquivo com molho especial no diretório em que você executa isso. Como mais de uma pessoa já apontou, não analise a saída de ls !
Stephen P
11

Nunca analise a saída de ls
Minha sugestão é evitar analisar a saída de ls [ 1 ] , ainda mais se estiver em conjunto com o delcomando. Isso por muitos motivos, principalmente relacionados a caracteres inesperados e não usuais permitidos no nome do arquivo.

Mesmo quando você espera que os nomes de arquivos pertencentes aos pacotes Linux "se comportem bem" , esse problema pode aparecer se outros arquivos estiverem presentes no mesmo diretório, mas você não sabia ou notou.

É melhor usar find, a expansão da guia (comece a escrever o nome e pressione Tab), a expansão do nome do arquivo [ 2 ] como *MyKey*...


Uma solução rápida
Como você deseja selecionar todos os pacotes (que terminam com .deb) com "google" dentro, você pode criar sua solicitação com o curinga * *google*.debe fazer um simples

rm -i *google*.deb 

que selecionará cada nome de arquivo com "google" no meio que terminará no .debpresente no diretório atual. A opção -i(interativa) solicitará a confirmação, um bom hábito ao excluir arquivos com a expansão de parâmetro.


Uma solução próxima à filosofia de sua tentativa
Se seu objetivo é criar sua linha de comando peça após peça, você fez isso lsdepois ls | grep googlee somente depois de verificar sua saída, é possível executá-la em uma subshell $(...)com

rm -i $(ls | grep google)

Uma maneira mais rápida e perigosa [ 3 ] , é usar!!

ls | grep google
rm -i $(!!)

que executará o último comando concluído em seu histórico . Você pode proteger-se do fato de que você não tem controle visual da linha que você está indo para executar se você tiver ativado previamente as opções do shell histverifycom shopt -s histverify.

Hastur
fonte
5
touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;

< rm ... ./0 > ? y
< rm ... ./9 > ? y
< rm ... ./8 > ? y
< rm ... ./7 > ? y
< rm ... ./6 > ? y
< rm ... ./5 > ? y
< rm ... ./4 > ? y
< rm ... ./3 > ? y
< rm ... ./2 > ? y
< rm ... ./1 > ? y
^C

... use -name '*c*.deb'ou algum outro padrão que combina com você.

mikeserv
fonte
2

rmnão aceita entrada de stdin. Você precisará fazer algo comols google-chrome* | xargs rm

David King
fonte