Como fazer o loop de uma lista cada vez maior de arquivos no bash?

4

Eu tenho um gerador de arquivos em execução, onde cada arquivo tem um nome em ordem alfabética após o anterior. No começo eu estava fazendo meu loop como for file in /path/to/files*; do... , mas logo percebi que o glob só se expande antes do loop, e qualquer novo arquivo criado durante o loop não será processado.

Minha maneira atual de fazer isso é bem feia:

while :; do
    doneFileCount=$(wc -l < /tmp/results.csv)
    i=0
    for file in *; do
        if [[ $((doneFileCount>i)) = 1 ]]; then
            i=$((i+1))
            continue
        else
            process-file "$file" # prints single line to stdout
            i=$((i+1))
        fi
    done | tee -a /tmp/results.csv
done

Existe alguma maneira simples de fazer o loop de uma lista cada vez maior de arquivos, sem o hack descrito acima?

    
por Ruslan 03.12.2017 / 13:47

1 resposta

7

Eu acho que a maneira usual seria ter novos arquivos em um diretório, e renomeá-los / movê-los para outro após o processamento, para que eles não atinjam o mesmo glob novamente. Então, algo assim

cd new/
while true; do 
    for f in * ; do
        process file "$f" move to "../processed/$f"
    done
    sleep 1   # just so that it doesn't busyloop
done

Ou, da mesma forma, com uma extensão de arquivo em mudança:

while true; do 
    for f in *.new ; do
        process file "$f" move to "${f%.new}.done"
    done
    sleep 1   # just so that it doesn't busyloop
done

No Linux, você também pode usar inotifywait para receber notificações sobre novos arquivos.

inotifywait -q -m -e moved_to,close_write --format "%f" . | while read -r f ; do
    process file "$f"
done

Em ambos os casos, você desejará observar os arquivos que ainda estão sendo gravados. Um arquivo grande criado no local não aparecerá atomicamente, mas seu script pode começar a processá-lo quando estiver apenas parcialmente gravado.

O evento inotify close_write acima verá arquivos quando o processo de gravação os fechar (mas também capturar arquivos modificados), enquanto o evento create verá o arquivo quando for criado pela primeira vez (mas ainda pode ser gravado em ). moved_to simplesmente captura arquivos que são movidos para o diretório que está sendo assistido.

    
por 03.12.2017 / 14:07

Tags