TL;DR:
P: Como manter um contador em find -exec
loop?
Meu caso de uso:
Eu preciso mover muitos diretórios que estão espalhados pelo local, então eu faço
find . -type d -name "prefix_*" \
-exec sh -c '
new_path="/new/path/$(basedir "$1")";
[ -d "$new_path" ] || mv "$1" "$new_path";
' find_sh {} \;
(O comando real é mais complexo, pois li alguns metadados para a constituição do /new/path
. De qualquer forma, não quero discutir sobre o comando em si, não faz parte da questão, apenas o caso de uso).
Funciona muito bem, mas demora um pouco e eu quero acompanhar o progresso.
Então eu adicionei um contador de escrita em um arquivo:
i=$(cat ~/find_increment || echo 0);
echo $((i+1)) | tee ~/find_increment;
Isso também funciona bem, mas parece uma péssima ideia ter cerca de 100.000 operações de leitura e gravação de disco.
Pensei em escrever em ramdisk
vez de disco, mas não tenho essa opção no ambiente que preciso para realizar essa tarefa.
Existe uma maneira melhor de manter um contador entre as -exec
corridas?
find
Em vez de usar um comando puro , você pode combinarfind
com umwhile read
loop ou GNUparallel
. Ambos provavelmente serão mais rápidos do quefind
's ,-exec
já que você não inicia um novo shell para cada caminho encontrado porfind
.Solução usando GNU Parallel
GNU
parallel
tem os seguintes benefícios em comparação comwhile read
:IFS=
e-r
necessário.{#}
.Para strings de substituição mais úteis, dê uma olhada no tutorial .
Remova o
-j1
e você terá tantos trabalhadores quanto núcleos por padrão.O
{}
é substituído pelaparallel
entrada citada corretamente lida destdin
. Não cite{}
novamente.parallel
executa o script com o mesmo shell do qual você o iniciou. Se você começouparallel
,bash
pode usarbash
recursos no script.Solução usando durante a leitura
Se disponível, armazene o contador
/dev/shm/
para evitar gravações em disco.=> Use
/dev/shm/find_increment
em vez de~/find_increment
.