Às vezes, preciso renomear arquivos em lote para nomes de arquivos aleatórios ou pseudo-aleatórios, apenas oito letras minúsculas e dígitos, por exemplo, de mcmurdo-station.png
para algo como a12bc0xy.png
. Para isso, uso CRC32:
for f in *.png; do mv $f $(crc32 $f); done
Mas há uma desvantagem: se houver dois arquivos idênticos na mesma pasta, eles terão as mesmas somas de verificação e, portanto, haverá uma colisão de nomes de arquivo. É claro que normalmente não armazeno arquivos idênticos na mesma pasta, mas mesmo assim prefiro evitar essa automatização excessiva ao renomear em lote.
Outra forma que encontrei na internet é usar base64:
foo % randomname() { head -c8 /dev/urandom | base64 | tr -dc a-z0-9; }
zmv '(*).(*)' '`randomname`.$2'
Mas os nomes dos arquivos resultantes têm comprimentos diferentes: o primeiro arquivo de teste foi renomeado de foo.png
para 52rud.png
, enquanto o segundo foi renomeado de bar.png
para pxg.png
.
Também existe uma solução usando shuf
GNU Core Utils: https://unix.stackexchange.com/a/259761 , mas por enquanto eu preferiria encontrar uma maneira que não exija a instalação de pacotes de terceiros.
Qual é uma alternativa boa e simples?
Você pode simplesmente renomear os arquivos para um número incrementado e processá-los apenas em ordem aleatória.
Exemplo (aqui
-n
para simulação):Para uma string aleatória com
a-z
letras e0-9
dígitos, você poderia usar um número aleatório na base 36:Observe que, embora extremamente improvável, não é garantido que não haverá nenhuma colisão (embora
zmv
a detecte e saia antes de renomear, se isso acontecer).