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 ls
para xargs
. Em vez disso, canalize find ... -print0
para 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 rm
um curinga.
Normalmente, ls
separa find
nomes de arquivos com novas linhas, mas xargs
divide sua entrada por nova linhaouespaço, resultando no comportamento que você vê.
É possível xargs
dividir 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, -print0
diz find
para separar nomes de arquivos com um byte nulo; o mesmo para xargs -0
. (Algumas outras ferramentas também possuem opções semelhantes, como sort -z
ou grep -zZ
.)
A "versão curta" usa um curinga de shell simples ("padrão" embash
manual– consulte a seção "Expansão do nome do caminho").