Acelerando um comando find rm com teste por meio de paralelização

1

Eu quero excluir recursivamente todos os arquivos em diretórios e subdiretórios com número de linhas menor que 10 e atualmente estou usando o seguinte comando

find . -type f -name "*.txt" | while read; do     
(($(cat $THISFILE | wc -l) < 10)) && rm -vf "$THISFILE"; done 

Já usei find com xargs para paralelizar alguns comandos, mas aqui não sei como fazer isso por causa do teste em linhas com wc -l

Como eu poderia ir mais rápido com (ou sem!) xargs ?

    
por gdz 05.02.2013 / 11:23

1 resposta

3

encontrar-se não pode executar em paralelo (não que eu saiba).

O xargs pode fazer isso, e a maneira mais simples de fazer isso com xargs é envolvê-lo em um script de shell.

Mas antes disso, você deve otimizar sua condição em si. cat é inútil, a menos que realmente concatene arquivos. E você não precisa contar TODAS as linhas apenas para determinar se um arquivo tem 10 ou mais. Então eu sugiro uma condição como esta:

[ $(head -n 10 "$file" | wc -l) -lt 10 ] && echo rm "$file"

que lê apenas as primeiras 10 linhas no máximo e exclui o arquivo se ele não tiver tantas (rm é um pouco perigoso, então eu adicionei echo para que você possa testá-lo primeiro). Ao contrário do cat, o head realmente pára de ler depois de atingir 10 linhas, então se você tiver arquivos com mais de 10 linhas em seu diretório, isso deve acelerar muito o processo.

Envolvido em um script de shell da seguinte forma:

#!/bin/bash

for file in "$@"
do
    [ $(head -n 10 "$file" | wc -l) -lt 10 ] && echo rm "$file"
done

Você pode usar o find + xargs para multiprocessamento:

find . -type f -name "*.txt" -print0 | xargs -0 -P 4 -n 8 ./rm10lines.sh

O -P 4 (quatro processos) e -n 8 (8 argumentos por chamada para o shell script) são exemplos, ajuste ao seu gosto. Use um maior -n se você souber que tem muitos arquivos para reduzir a sobrecarga, reapresentando seu script de shell.

    
por 05.02.2013 / 12:05