é | grep | rm -- Como formatar este comando?

é | grep | rm -- Como formatar este comando?

Estou tentando excluir vários arquivos em um determinado diretório (no Mac OS X usando Terminal)

ls | grep \([1-9]\) | xargs rm

deveria funcionar, mas não funciona. Estou tentando excluir qualquer arquivo com um único dígito entre parênteses no nome do arquivo (duplicatas baixadas da web), mas acaba fazendo algo assim:

> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory

porque não interpreta o espaço corretamente. Deve excluir "520syllabus2010 (3).pdf"

Qual é a maneira correta de fazer isso?

Obrigado, Jeff

Responder1

Versão curta:

rm *\([1-9]\)*

Não canalize lspara xargs. Em vez disso, canalize find ... -print0para xargs -0, para evitar tais problemas.

find . -maxdepth 1 -name '*([1-9])*' -print0 | xargs -0 rm

...que pode ser escrito como:

find . -maxdepth 1 -name '*([1-9])*' -exec rm {} \;

e:

find . -maxdepth 1 -name '*([1-9])*' -delete

que pode ainda ser reduzido para apenas rmum curinga.


Normalmente, lssepara findnomes de arquivos com novas linhas, mas xargsdivide sua entrada por nova linhaouespaço, resultando no comportamento que você vê.

É possível xargsdividir apenas por nova linha, mas os arquivospodetambém têm novas linhas em seus nomes. Na verdade, no Linux e no BSD, oapenas personagem não permitidoé o"nulo"ou zero byte– então é o que você deve usar nesses casos.

No exemplo 2 acima, -print0diz findpara separar nomes de arquivos com um byte nulo; o mesmo para xargs -0. (Algumas outras ferramentas também possuem opções semelhantes, como sort -zou grep -zZ.)

A "versão curta" usa um curinga de shell simples ("padrão" embashmanual– consulte a seção "Expansão do nome do caminho").

informação relacionada