removido
(usa Nenhuma)
Enviado em 09/01/2020 - 16:09h
Update: minha resposta tinha funcionado anteriormente com 80 mil arquivos, mas a retestei e ela não funcionou de novo com 100 mil arquivos. Andei vendo e parece mesmo que existe um limite de buffer no Bash ou no kernel.. Ainda não achei uma forma fácil de alterar isso...
Update2: Para aumentar o valor de buffer dos processos da sua shell atual, use '$ ulimit -s 100000' antes. Se tiver 2 Gb sobrando de RAM (parece ser o limite máximo), pode colocar 'ulimit -s unlimited'. Mas isso é um hack , não é bom alterar o padrão do ulimit para sempre..
https://unix.stackexchange.com/questions/128559/solving-mv-argument-list-too-long
Testei aqui com o ulimit aumentado, e agora moveu 144 mil arquivos de boas..
Update3: Este artigo, em inglês, é o mais esclarecedor que consegui encontrar.. O problema com limite de memória é especificamente com comandos que usam exec(), ou seja, o 'mv'. Já a expansão do bash só é limitada pela memória virtual do seu sistema. De fato, se você usar 'echo *' em um dir com centenas de milhares de arq ele não vai apresentar esse problema já que o 'echo' é um built-in do bash e não usa uma função exec().. Veja os limites:
eu@archhost ~ $ xargs --show-limits
Your environment variables take up 2906 bytes
POSIX upper limit on argument length (this system): 2092198
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2089292
Então, para driblar esse limite, sem precisar alterar o ulimit, é usando um built-in do bash 'printf' pois ele não usa a função exec(), e depois o 'xargs'.
Por que isso é importante: se você usar o 'find .. -exec mv', ele vai abrir uma nova sub-shell para cada 'mv' que ele fizer, isso vai deixar o processo muuuito lento (é possível otimizar esse comando um pouco..). Um 'for loop' é OK e super portável, porém ele pode ser muito devagar.. O 'printf' e o 'mv' são built-ins do bash, ou seja executam super rápido. Já o 'xargs', só vai abrir *uma* subshell e depois executar os 'mv', e portanto é muito mais rápido.
$ printf '%s\0' *.webp | xargs -0 mv -t "$dirtemp"
O 'printf' vai mandar um caracter nulo ao invés de uma nova linha entre cada nome de arquivo, o que vai evitar problemas com nomes com caracteres em branco, e será lido corretamente pelo 'xargs' com opção '-0'. Opção -t do 'mv' é para indicar corretamente qual o destino dos arquivos.
https://www.in-ulm.de/~mascheck/various/argmax/
---Antigo post---
O problema com o seu script não é o fato de você ter muitos arquivos. A mensagem de erro é enganosa, pois é um erro que advém (opa palavras difíceis, imprecionante) de como o Bash interpreta os nomes dos arquivos, já que a estrela * é um coringa e irá listar todos os nomes dos arquivos que casarem com o padrão *.webp
Porém, no seu caso, o problema é mesmo por que você deve ter nomes de arquivos com espaço em branco ou caracteres especiais.
Ao invés de usar o find, que é um desperdício de CPU e de tempo, use travessão -- antes dos argumentos do mv para o Bash interpretar corretamente os nomes dos arquivos.
mv -- *.webp $dirtemp
PS: testei com 80mil arquivos aqui com espaço em branco no nome e foi de boas.