Pode ser que você já tenha tentado dar um comando usando o asterisco * na bash e tenha obtido este erro:
bash: comando: Argument list too long
Aonde comando pode ser um rm, ou um cp, ou qualquer outro. Por exemplo:
daniduc@nicholas:~/teste$ rm -f * bash: /bin/rm: Argument list too long daniduc@nicholas:~/teste$
Quem imprimiu esse erro não foi o comando (o rm, no exemplo), mas a bash, que é responsável por expandir o wildcard *, substituindo-o pela lista de arquivos no diretório. Em sistemas UNIX, há um limite fixo de memória reservado para o ambiente e lista de parâmetros de um comando. No caso do meu servidor Linux, esse limite é 128K, mas isso varia de sistema para sistema. Você pode descobrir no seu sistema usando o comando getconf. Veja:
daniduc@nicholas:~/teste$ getconf ARG_MAX 131072 daniduc@nicholas:~/teste$
Agora, ao que interessa. Como fazer para remover os arquivos do meu exemplo acima? Existem diversas saídas, variando a eficiência dependendo de qual é o seu comando, na verdade. Mas vamos ver o rm, pois o exemplo dele pode ser aplicado a outros, como por exemplo o cp, ou o mv.
Se você puder eliminar o diretório inteiro no qual estão os arquivos, não há problemas:
daniduc@nicholas:~$ rm -rf teste/ daniduc@nicholas:~$
Se você só pode eliminar os arquivos, uma saída é usar o comando find.
daniduc@nicholas:~/teste$ find . -type f -exec rm -f {} \; daniduc@nicholas:~/teste$
Nesse caso, eu pedi para o find encontrar no diretório em que estou (.) todos os arquivos (-type f) e para cada um deles executar (-exec) o comando rm. As chaves {} são substituídas por cada arquivo encontrado pelo find. Dessa forma o rm é executado uma vez para cada arquivo, tendo assim apenas aquele arquivo como parâmetro, o que evita ultrapassar o limite de memória imposto. O final \; é para fechar o comando do -exec com um ponto e vírgula, que precisa ser precedido da contra barra (\) para que a bash não o interprete (uma vez que ; é um caractere com sentido especial para a bash) e apenas o passe para o find.
Caso, por exemplo, você precise remover somente os arquivos html e não os arquivos .php em um diretório, basta usar o find novamente:
daniduc@nicholas:~/teste$ ls *.php 1.php 2.php daniduc@nicholas:~/teste$ ls (saida resumida:) 23497.html 36998.html 50498.html 6399.html 774.html 9.html 23498.html 36999.html 50499.html 639.html 77500.html 23499.html 3699.html 5049.html 63.html 77501.html 2349.html 369.html 504.html 64000.html 77502.html 234.html 36.html 50500.html 64001.html 77503.html
daniduc@nicholas:~/teste$ find . -name \*.html -exec rm -f {} \; daniduc@nicholas:~/teste$ ls 1.php 2.php daniduc@nicholas:~/lixo
Aqui o asterisco funciona porque está precedido pela contrabarra o que faz com que a bash não o interprete, apenas o find. E o find não expande o asterisco em todos os arquivos do diretório, como a bash. Para o find, o asterisco é parte de uma expressão regular, que quer dizer encontre arquivos cujo nome seja qualquer coisa seguida de um .html .
Eu uso a versão da GNU do find, presente na maioria dos sistemas Linux. Caso o seu find não entenda o parâmetro -exec, use-o em conjunto com comando xargs:
daniduc@nicholas:~/teste$ find . -name \*.html | xargs rm -f daniduc@nicholas:~/teste$ ls 1.php 2.php daniduc@nicholas:~/teste$