ls | grep | rm - Como formatar este comando?

11

Estou tentando excluir um monte de arquivos em um determinado diretório (no Mac OS X usando o Terminal)

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

deve fazer o truque, mas não. 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. Ele deve excluir "520syllabus2010 (3) .pdf"

Qual é a maneira correta de fazer isso?

Obrigado Jeff

Jeff
fonte
1
O nome do arquivo de exemplo não contém um literal #.
Benjamin Bannier
1
@honk: Ele não está procurando um literal #.
Ignacio Vazquez-Abrams
1
Devido à expansão pelo shell, isso não funcionará como esperado se o cwd tiver um arquivo chamado por exemplo (3). É melhor citar argumentos para que o shell não os afete.
Ignacio Vazquez-Abrams
1
Você está sendo atingido pelo problema separador en.wikipedia.org/wiki/Xargs#The_separator_problem
Ole Tange

Respostas:

19

Versão curta:

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

Não canalize lspara xargs. Em vez disso, passe find ... -print0para xargs -0, a fim de 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 rmcom um curinga.


Normalmente, lse findsepare os nomes de arquivo com novas linhas, mas xargsdivida sua entrada por nova linha ou espaço, resultando no comportamento que você vê.

É possível dizer xargspara dividir apenas por nova linha, mas os arquivos também podem ter novas linhas em seus nomes. De fato, no Linux e no BSD, o único caractere não permitido é o byte "nulo" ou zero - portanto é 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 têm opções semelhantes, como sort -zou grep -zZ.)

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

user1686
fonte
1
E, para garantir a segurança, é melhor usá- *" "\\([1-9]\\).*lo para que apenas os arquivos com um espaço antes do número pareado antes do período (a, para ser justo) sejam excluídos.
Ignacio Vazquez-Abrams
Não estou muito familiarizado com essa sintaxe, mas com base nos votos positivos, tentei e o que você sabe ... funcionou! Obrigado!
Jeff
1
+1. -print0 é essencial para a tubulação correta para xargs.
Chris W. Rea