Piping find -name para xargs resulta em nomes de arquivos com espaços não sendo passados ​​para o comando

26

Normalmente, para remover arquivos com espaços em seus nomes de arquivo, você teria que executar:

$ rm "file name"

mas se eu quiser remover vários arquivos, por exemplo:

$ find . -name "*.txt" | xargs rm

Isso não excluirá arquivos com espaços neles.

Ashley
fonte
Adivinhação completa aqui: find -name "*\ *.txt" | xargs rmfunciona para arquivos com duas palavras?
TheWanderer

Respostas:

49

Você pode dizer finde xargsusar terminadores nulos

find . -name "*.txt" -print0 | xargs -0 rm

ou (mais simples) use a -deleteação interna defind

find . -name "*.txt" -delete

ou (obrigado @kos)

find . -name "*.txt" -exec rm {} +

qualquer um deles deve respeitar o ARG_MAXlimite do sistema sem a necessidade xargs.

chave de aço
fonte
1
Não pode upvote-lo :) duas vezes difícil já que você mencionou ARG_MAXeu também vou mencionar que find . -name "*.txt" -exec rm {} \;seria um "tiro seguro"
kos
3
Assim diz o mestre: lembre-se sempre de xargs -0.
Joshua Joshua
1
Ponto super importante: -print0deve ser a última opção (ou pelo menos após -name "*.txt"), caso contrário este vai bater arquivos já não se limita a*.txt ...
Kev
1

Aliás, se você usou algo diferente de find, poderá usar tr para substituir as novas linhas por bytes nulos.

Por exemplo. o liner a seguir exclui os 10 últimos arquivos modificados em um diretório, mesmo que eles tenham espaços em seus nomes.

ls -tp | grep -v / | head -n 10 | tr "\n" "\0" | xargs -0 rm

Ibrahim
fonte
Sim, isso funciona.
Peter Mortensen
0

O comando xargs usa tabulações, espaços e novas linhas como delimitadores por padrão. Você pode dizer para ele usar apenas caracteres de nova linha ('\ n') com a opção -d:

find . -name "*.txt" | xargs -d '\n' rm

Resposta de origem no SO .

joseph_morris
fonte
Essa resposta menciona em -0vez de -d(para xargs) para sistemas BSD. O que o Ubuntu usa? A resposta aceita aqui usa -0. O que é correto?
Peter Mortensen