xargs com espaços contendo rm + filename

0

Estou escrevendo um programa simples que exclui todos os arquivos obtidos. Os arquivos podem conter espaços, então adicionei as cotações como visto abaixo

find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"

O texto acima falha com erro: não é possível remover nenhum arquivo ou diretório. Mas se eu listar os mesmos arquivos eles estão lá. Além disso, se eu fizer abaixo e usar bash para executá-lo; funciona

find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash

Alguém por favor pode explicar porque o 1º cenário não funcionou?

    
por LoveWithMaths 05.04.2018 / 15:41

1 resposta

5
xargs -d "\n" -I {} rm \"{}\"

Isso pressupõe a versão do xargs do coreutils que suporta a opção -d para especificar o delimitador.

Isso não funcionará junto com o comando find porque ele adiciona aspas duplas aos nomes de caminho encontrados por find . Isso significa que, em vez de ./somedir/file.scala , a chamada para rm é feita com o literal pathname "./somedir/file.scala" .

Exemplo:

$ touch hello
$ touch '"hello"'
$ ls
"hello" hello
$ echo hello | xargs -d "\n" -I {} rm \"{}\"
$ ls
hello

Funciona quando você canaliza os comandos gerados para bash porque bash faz a remoção da cotação.

Provavelmente também teria funcionado se você não tivesse feito o esforço extra para adicionar as cotações em primeiro lugar:

xargs -d "\n" -I {} rm {}

Para excluir seus arquivos corretamente, use

find . -type f -name '*.scala' -delete

ou, se você ainda quiser usar xargs :

find . -type f -name '*.scala' -print0 | xargs -0 rm

que passa os nomes de caminho entre find e xargs como uma lista delimitada por nul. Nul ( / ) é o caractere somente que não é permitido em um nome de caminho em sistemas Unix. Os nomes de arquivos também não podem conter rm , mas novas linhas são permitidas.

Uma terceira opção seria chamar find diretamente de {} :

find . -type f -name '*.scala' -exec rm {} +

Note que find não precisa ser (e não deve ser) citado como %code% sabe perfeitamente como passar nomes de caminho com espaços (ou novas linhas ou qualquer que seja) para o utilitário nomeado.

    
por 05.04.2018 / 16:12