ls | grep | rm - Como formatar este comando?

11

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

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

deve fazer o truque, mas isso não acontece. Eu estou tentando excluir qualquer arquivo com um único dígito entre parênteses no nome do arquivo (duplicados baixados da web), mas acaba fazendo algo parecido com isto:

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

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

Qual é a maneira correta de fazer isso?

Obrigado Jeff

    
por Jeff 31.01.2011 / 21:33

1 resposta

19

Versão resumida:

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

Não canalize ls para xargs . Em vez disso, canalize find ... -print0 para xargs -0 , para evitar esses 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 ser reduzido para apenas rm com um caractere curinga.

Normalmente, ls e find separam nomes de arquivos com novas linhas, mas xargs divide sua entrada por espaço newline ou , resultando no comportamento que você vê.

É possível dizer xargs para dividir apenas por nova linha, mas os arquivos podem ter novas linhas em seus nomes também. De fato, no Linux e no BSD, o somente caractere desaprovado é o " null " ou zero byte - então é o que você deve usar em tais casos.

No exemplo 2 acima, -print0 informa find para separar nomes de arquivos com um byte nulo; mesmo para xargs -0 . (Algumas outras ferramentas também têm opções semelhantes, como sort -z ou grep -zZ .)

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

    
por 31.01.2011 / 21:45

Tags