¿Cómo crear un archivo desde la terminal repitiendo un conjunto de palabras infinitamente?


19

¿Cómo crear un archivo desde la terminal repitiendo un conjunto de palabras infinitamente? Lo necesito para crear un archivo enorme con fines de análisis como 2-4GB de tamaño. Actualmente estoy copiando manualmente líneas de pegado en el mismo archivo para aumentar el tamaño.


1
Me gustaría ver una respuesta que funcione con archivos especiales de Unix, para que realmente no ocupe ese espacio. ¿Es eso posible?
Délisson Junio

1
¿Te refieres a algo realmente infinito mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

Respuestas:


50

Hay una manera fácil de repetir una línea muchas veces:

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

dará como resultado out.txt que contiene 10,000 líneas que dicen "no tenemos plátanos".


Para limitar la salida a un número exacto de bytes, use headla -copción 's en lugar de -n. Por ejemplo, esto genera exactamente 10 kB de texto:

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

2
OP quiere tratar con bytes, no líneas.
heemayl

44
Para especificar un límite en bytes, simplemente use head -c 10000para 10 kB en lugar de head -n 10000para 10k líneas.
Byte Commander

@ByteCommander sí, pero eso no evitará que la salida se corte en el medio de una línea. Dado que el tamaño no tiene que ser preciso, simplemente calcularía el número de líneas para obtener el tamaño correcto y redondearía :)
hobbs

1
Estoy de acuerdo, pero tampoco estoy seguro de si eso sería un problema. El OP no especificó qué método quiere, pero su respuesta aún contiene ambos. Ah, y felicidades por duplicar su puntaje de reputación hoy :)
Byte Commander

@ByteCommander sí, claro.
hobbs

10

No puedo recomendar el texto que se repite infinitamente , pero podría hacer un archivo de ~ 2GB de texto repetido con Python así ...

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

Eso imprimirá "hola mundo" 10 veces y hará una nueva línea, y repita eso 20,000,000 veces, escribiendo el resultado en el archivo bigfile. Si todos sus caracteres son ASCII, cada uno es un byte, así que calcule adecuadamente según lo que quiera escribir ...

Su CPU puede ser de su propiedad. Me quedo sin RAM si intento hacer más de 10,000,000 de líneas ...

Aunque estoy corriendo una tostadora


OP quiere tratar con bytes, no líneas.
heemayl

@heemayl, por supuesto, su respuesta es mejor, pero he explicado (vagamente) cómo calcular cuántas líneas usar para obtener los bytes deseados, así que no creo que mi respuesta sea completamente inútil
Zanna

44
@heemayl, ¿qué te hace estar tan seguro de que el OP quiere bytes? La pregunta esencialmente establece que el OP quiere un archivo grande. El tamaño específico es muy vago (2-4 GB), por lo que realmente dudo que haya un límite de bytes específico en mente.
terdon

1
@heemayl sí, pero eso es muy, muy vago. Tengo entendido que el OP solo quiere un archivo grande y no le importa un tamaño exacto. De lo contrario, habrían dado un tamaño en lugar de una gama tan grande de tamaños.
terdon

1
@cat ikr! <3python <3
Zanna

9

Perl tiene el ingenioso xoperador:

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

Entonces, como una solución simple, podría escribir su línea unos pocos millones de veces. Por ejemplo, este comando creó un archivo 3G:

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

Si necesita especificar un tamaño exacto (2 GiB en este caso), puede hacer:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file

Si tiene paciencia, puede usar operadores de Perl 6 geniales, excepto que Perl 6 es mucho, mucho, mucho más lento: D
cat

@cat es realmente? No he tocado 6 en absoluto, pero asumí que solo tendría toda la bondad perly más extras OO. ¿Alguna idea de por qué es más lento?
terdon

1
Mi comentario fue principalmente simplista, pero descubrí a principios de este año que Perl 6 es bastante lento, en comparación con Python 3, que es canónicamente mucho más lento que Perl 5 (que no probé). El trabajo se centra en las características y la corrección, aún no en el rendimiento, pero se incluyó como objetivo para 2015. Además, ¿Perl 6 es lo suficientemente rápido para mí? .
gato

(Por otro lado, la lista de características es impresionante por decir lo menos.)
gato

7
  • Ponga el conjunto de palabras que se repetirán en un archivo, por ejemplo source.txt. Obtenga el tamaño de source.txt, en bytes, por ejemplo, por:

     stat -c '%s' source.txt
    
  • Decida el tamaño del archivo de destino, por ejemplo destination.txt, 2 GB o 4 GB o lo que sea. Convierte el tamaño en bytes.

  • Divida el tamaño del archivo de destino por el tamaño del archivo de origen. bashno puede hacer aritmética de coma flotante, pero no es necesaria en este caso.

  • Use una forconstrucción para repetir una cat source.txtoperación el resultado de la división veces. Esta sería la aproximación más cercana al tamaño del archivo de destino que puede obtener por repetición. La salida de la operación se guarda en destination.txt.

Por ejemplo, suponiendo que source.txtes de 30 bytes, y queremos crear un archivo de 2 GB, necesitamos:

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

Aquí estoy estableciendo el límite superior ((16777216/30))en el momento de la inicialización; puedes obtener el resultado y ponerlo aquí también.

La operación llevaría algún tiempo; cuanto mayor sea source.txt, menos tiempo se necesitará.


1
¿No se abre y cierra destination.txtuna vez por cada iteración del ciclo?
Restablece a Monica - ζ--

@hexafraction Duh, fijo.
heemayl

6

También puedes usar un whilebucle.

Ejemplo: Contenido de foo.txt(Esta es su fuente):

foo
bar
foobar

bar.txtestá vacío (este es su archivo de destino). Ahora puede ejecutar el siguiente ciclo para escribir el contenido de foo.txtvarias veces bar.txt:

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

Explicación:

  • stat --format "%s" bar.txtmuestra el tamaño de bar.txten bytes.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] Las siguientes acciones se repetirán hasta que se alcance el tamaño de destino (en este caso 150 bytes).
  • cat foo.txt >> bar.txtagregar el contenido de foo.txtabar.txt

4

primero de disparar el comando:

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

creará un archivo en la ruta de tamaño bs * contar bytes aleatorios, en nuestro caso 2048 * 10 = 20Kb. eso se puede cambiar según el requisito.

cat - > file.txt

Este comando redirige STDIN a un archivo, por lo que deberá ingresar dos líneas y luego presionar Ctrl + D. Luego deberá ejecutar el siguiente comando:

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

Donde n es un número entero. Esto creará un archivo con 2 ^ (n + 1) líneas, duplicando las dos líneas originales. Entonces, para crear un archivo con 16 líneas, haría:

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

Aquí hay algunos números más para comenzar:

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)

2
OP quiere tratar con bytes, no líneas.
heemayl

OP también mantiene una línea de afrontamiento para llenar el archivo. y mi primer comando ya creó el archivo según los bytes requeridos de memoria.
Avani badheka

@heemayl el carácter de nueva línea todavía ocupa un byte, igual que mi comentario anterior. Es un personaje legítimo. Sin embargo, el OP especificó palabras , Avani, por lo que no creo que su técnica / dev / urandom responda a su pregunta.
Mike S

Depende de / dev / urandom, si está intentando algunos bytes aleatorios. Incluso puede elegir sus propios archivos que contienen tantos bytes de datos.
Avani badheka

4

Los FIFO son probablemente lo que estás buscando. En lugar de llamar a su programa con un archivo determinado, puede vincular el resultado de un comando de shell a través de la subtitulación del proceso y el programa verá su salida como un archivo de texto sin formato. La ventaja aquí es que ya no está limitado por su espacio en el disco, por lo que puede alcanzar tamaños de archivo que de otra forma serían imposibles, siempre y cuando su programa no necesite almacenar primero el archivo completo y simplemente analizarlo línea por línea. Por ejemplo, usando la respuesta de @hobbs para generar contenido:

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

Esto me presta un archivo de 95 gigabytes (de acuerdo con wc) sin costo en el espacio del disco duro y apenas RAM, solo lo suficiente para almacenar lo que devuelve el comando antes de que se lea. Esto es lo más cercano a "infinitamente" que vas a tener.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.