Eu quero gerar alguns arquivos grandes para algum experimento.
Este é o meu roteiro. Ele cria um arquivo, em seguida, o lê para uma variável e tenta escrevê-lo quantas vezes forem definidas no loop em arquivos:
#! /usr/bin/env bash
set -e
set -u
< /dev/urandom tr -dc "\t\n [:alnum:]" | head -c32768 > temp.txt
data=$(cat ./temp.txt)
for testdir in "$@"; do
echo "create directory '$testdir'"
mkdir -p $testdir
for i in {1..3}; do
counter=$(printf %02d $i)
testfile=$testdir/test_${testdir##*/}_$counter.txt
echo "create file '$testfile'"
echo "$data" > $testfile
done
done
Se eu tentar usar este script para criar 3000 arquivos (cada pasta terá 3 arquivos) demora cerca de 19s no meu sistema:
tempo generateUserData.sh TESTE{0..1000}
create directory 'TEST999'
create file 'TEST999/test_TEST999_01.txt'
create file 'TEST999/test_TEST999_02.txt'
create file 'TEST999/test_TEST999_03.txt'
create directory 'TEST1000'
create file 'TEST1000/test_TEST1000_01.txt'
create file 'TEST1000/test_TEST1000_02.txt'
create file 'TEST1000/test_TEST1000_03.txt'
real 0m19.333s
user 0m14.791s
sys 0m4.784s
O reconhecimento echo
pode ser a parte lenta aqui. Alguma ideia de como posso fazer o dele o mais rápido possível?
O que seria lento seria bifurcar processos e executar comandos externos como
mkdir
Também bifurca um processo no bash. Isso pode ser evitado escrevendo-o como:
Ou:
Crie todo o diretório com uma
mkdir
invocação (mkdir -p -- "$@"
; não esqueça do--
) em vez de executar umamkdir
por arquivo.Também não há necessidade de um arquivo temporário:
A adição de
.
é necessária se você deseja$data
ter a garantia de conter 32768 bytes, pois a substituição de comando remove todos os caracteres de nova linha à direita. Observe também queecho
sem-n
adiciona um de volta.printf
deve ser usado em vez de deecho
qualquer maneira para dados arbitrários:Também tenha cuidado
head -c 32768
, pois fornece 32768 bytes, não caracteres, portanto, pode cortar caracteres no meio.Assumindo um pouco do que Stéphane Chazelas disse em sua boa resposta, com alguns ajustes.
dd
- maneira alternativa de obter o número exato de bytes (embora isso aconteça apenas uma vez, não fará muita diferença de qualquer maneira)echo
adicionados cerca de 3 segundos do meu lado com uma contagem de 1000proc
variável) - brinque para encontrar o valor ideal para o seu sistemapor exemplo
NB - supondo que sua pergunta original sobre o preenchimento da variável fosse uma instância de um problema XY ... se isso for um requisito difícil, minha resposta não é válida conforme escrita.
Essa alteração deve fazê-lo:
A segunda
dd
é ter certeza de que obtemos apenas os dados gerados, sem eles, em algum lugar entre$( )
e<<<
parece que encontramos um byte extra de algum lugar (nova linha implícita?). Feliz em receber correções sobre isso. Parece um pouco complicado, admito, se o tamanho dos dados aleatórios for arbitrário ou sem importância, você pode simplificar isso, tenho certeza