Como criar um arquivo do terminal repetindo um conjunto de palavras infinitamente?

19

Como criar um arquivo do terminal repetindo um conjunto de palavras infinitamente? Preciso criar um arquivo enorme para fins de análise, como 2 a 4 GB de tamanho. Atualmente, estou copiando manualmente as linhas de colagem no mesmo arquivo para aumentar o tamanho.

Nisheet
fonte
1
Eu gostaria de ver uma resposta trabalhando com arquivos unix especiais, para que ele não ocupasse esse espaço. Isso é possível?
Délisson Junio ​​27/09/16
1
Você quer dizer algo verdadeiramente infinito mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
precisa saber é o seguinte

Respostas:

50

Há uma maneira fácil de repetir uma linha várias vezes:

yes we have no bananas | head -n 10000 > out.txt

resultará em out.txt contendo 10.000 linhas, todas dizendo "não temos bananas".


Para limitar a saída a um número exato de bytes, use heada -copção em vez de -n. Por exemplo, isso gera exatamente 10 kB de texto:

yes we have no bananas | head -c 10000 > out.txt
hobbs
fonte
2
O OP quer lidar com bytes, não com linhas.
heemayl
4
Para especificar um limite em bytes, basta usar head -c 1000010 kB em vez de head -n 1000010 k linhas.
Byte Commander
@ByteCommander sim, mas isso não impedirá que a saída seja cortada no meio de uma linha. Uma vez que o tamanho não tem que ser preciso, gostaria apenas de descobrir o número de linhas para obter o tamanho certo, e se volta :)
Hobbs
1
Concordo, mas também não tenho certeza se isso seria um problema. O OP não especificou qual método ele deseja, mas sua resposta ainda contém os dois. Ah, e parabéns por dobrar sua pontuação de reputação hoje :)
Byte Commander
@ByteCommander sim, justo.
Hbbs
10

Não recomendo a repetição infinita de texto, mas você pode criar um arquivo de ~ 2 GB de texto repetido com python assim ...

python3 -c 'with open("bigfile", "w") as f: f.write(("hello world "*10+"\n")*2*10**7)'

Isso imprimirá "olá mundo" 10 vezes e criará uma nova linha e repetirá 20.000.000 vezes, escrevendo o resultado no arquivo bigfile. Se todos os seus caracteres forem ASCII, cada um será um byte, portanto calcule adequadamente, dependendo do que você deseja escrever ...

Seu processador pode ser de propriedade. Fico sem memória RAM se tentar fazer mais de 10.000.000 de linhas ...

Estou usando uma torradeira

Zanna
fonte
O OP quer lidar com bytes, não com linhas.
heemayl
@heemayl, claro, sua resposta é melhor, mas eu tenho (vagamente) explicou como calcular quantas linhas a utilizar para obter bytes desejados, então eu não acho que a minha resposta é totalmente inútil
Zanna
4
@heemayl o que faz você ter certeza de que o OP quer bytes? A questão afirma essencialmente que o OP quer um arquivo grande. O tamanho específico é muito vago (2-4 GB), então eu realmente duvido que haja um limite de bytes específico em mente.
terdon 27/09/16
1
@ heemayl sim, mas isso é muito, muito vago. Meu entendimento é que o OP quer apenas um arquivo grande e não se importa com o tamanho exato. Caso contrário, eles teriam dado um tamanho em vez de uma variedade tão grande de tamanhos.
terdon 27/09/16
1
@cat ikr! <3python <3
Zanna
9

Perl tem o xoperador bacana :

$ perl -e 'print "foo\n" x 5'
foo
foo
foo
foo
foo

Portanto, como uma solução simples, você pode escrever sua linha alguns milhões de vezes. Por exemplo, este comando criou um arquivo 3G:

perl -e 'print "This is my line\n" x 200000000' > file

Se você precisar especificar um tamanho exato (2 GiB neste caso), poderá:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file
Terdon
fonte
Se você está doente, você pode usar arrefecer Perl 6 operadores exceto Perl 6 é muito, muito, muito, muito mais lento: D
cat
@cat é mesmo? Ainda não toquei em seis, mas presumi que ele teria toda a bondade, mais os extras de OO. Alguma idéia de por que é mais lento?
terdon 27/09/16
1
Meu comentário foi bastante superficial, mas descobri no início deste ano que o Perl 6 é bastante lento, em comparação com o Python 3, que é canonicamente muito mais lento que o Perl 5 (que eu não testei). O trabalho está focado em recursos e correção, ainda não no desempenho, mas foi listado como uma meta para 2015. Além disso, o Perl 6 é rápido o suficiente para mim? .
cat
(Por outro lado, a lista de recursos é impressionante para dizer o mínimo.)
cat
7
  • Coloque o conjunto de palavras a serem repetidas em um arquivo, por exemplo source.txt. Obtenha o tamanho de source.txt, em bytes, por exemplo:

     stat -c '%s' source.txt
    
  • Decida o tamanho do arquivo de destino destination.txt, por exemplo , 2 GB ou 4 GB ou qualquer outra coisa. Converta o tamanho em bytes.

  • Divida o tamanho do arquivo de destino pelo tamanho do arquivo de origem. bashNão é possível fazer aritmética de ponto flutuante, mas não é necessário neste caso.

  • Use uma forconstrução para repetir uma cat source.txtoperação vezes o resultado da divisão. Isso seria o mais próximo possível do tamanho do arquivo de destino que você pode obter por repetição. A saída da operação é salva em destination.txt.

Por exemplo, supondo que source.txtseja de 30 bytes e desejemos criar um arquivo de 2 GB, precisamos:

for ((i=0; i<=((16777216/30)); i++)); do cat source.txt; done >destination.txt

Aqui estou definindo o limite superior ((16777216/30))no momento da inicialização; você pode obter o resultado e colocá-lo aqui também.

A operação levaria algum tempo; quanto maior source.txt, menos tempo será necessário.

heemail
fonte
1
Isso não abre e fecha destination.txtuma vez para cada iteração do loop?
Reinstate Monica - Sep--
@hexafraction Duh, corrigido.
precisa saber é o seguinte
6

Você também pode usar um whileloop.

Exemplo: Conteúdo de foo.txt(Esta é a sua fonte):

foo
bar
foobar

bar.txtestá vazio (este é o seu arquivo de destino). Agora você pode executar o seguinte loop para gravar o conteúdo foo.txtvárias vezes bar.txt:

while [ $(stat --format "%s" bar.txt) -lt 150 ] 
do 
    cat foo.txt >> bar.txt
done

Explicação:

  • stat --format "%s" bar.txtexibe o tamanho bar.txtem bytes.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] as ações a seguir serão repetidas até que o tamanho do destino (neste caso, 150 bytes) seja atingido.
  • cat foo.txt >> bar.txtanexar o conteúdo de foo.txtparabar.txt
Wayne_Yux
fonte
4

primeiro de disparar o comando:

dd if=/dev/urandom of=file.txt bs=2048 count=10

criará um arquivo no caminho de tamanho bs * count bytes aleatórios, no nosso caso 2048 * 10 = 20Kb. isso pode ser alterado conforme o requisito.

cat - > file.txt

Esses comandos redirecionam STDIN para um arquivo, portanto, você precisará inserir duas linhas e pressionar Ctrl + D. Então você precisará executar o seguinte comando:

for i in {1..n}; do cat file.txt file.txt > file2.txt && mv file2.txt file.txt; done

Onde n é um número inteiro. Isso criará um arquivo com 2 ^ (n + 1) linhas, duplicando as duas linhas originais. Então, para criar um arquivo com 16 linhas, você faria:

for i in {1..3}; do cat file.txt file.txt > file2.txt && mv file2.txt file.txt; done

Aqui estão mais alguns números para você começar:

n=15 will give you 65536 lines (if the original two lines were 'hello' and 'world' the file will be 384Kb)
n=20 will give you 2097152 lines (12Mb file with 'hello' and 'world' as the two starting lines)
n=25 will give you 67108864 lines (384Mb file with 'hello' and 'world' as the two starting lines)
Avani badheka
fonte
2
O OP quer lidar com bytes, não com linhas.
heemayl
OP também é manter a linha de enfrentamento para preencher o arquivo. e meu primeiro comando já criou o arquivo conforme os bytes de memória necessários.
Avani badheka
@heemayl o caractere de nova linha ainda ocupa um byte, igual ao meu comentário anterior. É um personagem legítimo. No entanto, o OP especificou palavras Avani, então não acho que sua técnica / dev / urandom responda à pergunta deles.
Mike S
Depende de / dev / urandom, se você está tentando alguns bytes aleatórios. Mesmo você pode escolher alguns arquivos que contêm muitos bytes de dados.
Avani badheka
4

Provavelmente, os FIFOs são o que você está procurando. Em vez de chamar seu programa com um determinado arquivo, você pode vincular o resultado de um comando do shell a ele via subtítulo do processo e o programa verá sua saída como um arquivo de texto sem formatação. A vantagem aqui é que você não está mais limitado pelo espaço em disco, para poder atingir tamanhos de arquivo que seriam impossíveis, caso contrário, desde que o seu programa não precise armazenar o arquivo inteiro em primeiro lugar e apenas possa analisá-lo linha a linha. Por exemplo, usando a resposta de @hobbs para gerar conteúdo:

wc -c <(yes we have no bananas | head -n 5000000000)

Isso me empresta um arquivo de 95 gigabytes (de acordo com o wc) sem nenhum custo no espaço do disco rígido e quase nenhuma RAM, apenas o suficiente para armazenar em buffer o que o comando retorna antes de ser lido. Isso é o mais próximo possível do "infinito".

Santo Guevarra
fonte