Comment créer un fichier depuis un terminal en répétant un ensemble de mots à l'infini?

19

Comment créer un fichier depuis un terminal en répétant un ensemble de mots à l'infini? J'en ai besoin pour créer un énorme fichier à des fins d'analyse comme une taille de 2 à 4 Go. Actuellement, je copie manuellement les lignes de collage dans le même fichier pour augmenter la taille.

Nisheet
la source
1
J'aimerais voir une réponse fonctionner avec des fichiers Unix spéciaux, afin qu'elle n'occupe pas réellement cet espace. Est-ce possible?
Délisson Junio
1
Vous voulez dire quelque chose de vraiment infini mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

Réponses:

50

Il existe un moyen simple de répéter une ligne plusieurs fois:

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

se traduira par out.txt contenant 10 000 lignes disant toutes "nous n'avons pas de bananes".


Pour limiter la sortie à un nombre exact d'octets, utilisez headl' -coption de au lieu de -n. Par exemple, cela génère exactement 10 Ko de texte:

yes we have no bananas | head -c 10000 > out.txt
Hobbs
la source
2
OP veut traiter les octets, pas les lignes.
heemayl
4
Pour spécifier une limite en octets, utilisez simplement head -c 1000010 Ko au lieu de head -n 1000010 000 lignes.
Byte Commander
@ByteCommander oui, mais cela n'empêchera pas la sortie d'être coupée au milieu d'une ligne. Comme la taille n'a pas besoin d'être précise, je devrais simplement déterminer le nombre de lignes pour obtenir la bonne taille, et arrondir :)
hobbs
1
Je suis d'accord, mais je ne suis pas sûr que ce soit un problème non plus. L'OP n'a pas précisé quelle méthode il veut, mais votre réponse contient toujours les deux. Oh, et félicitations pour avoir doublé votre score de réputation aujourd'hui :)
Byte Commander
@ByteCommander oui, juste.
Hobbs
10

Je ne peux pas recommander de répéter du texte à l' infini , mais vous pouvez créer un fichier ~ 2 Go de texte répété avec python comme ça ...

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

Cela imprimera "bonjour le monde" 10 fois et fera une nouvelle ligne, et répétera cela 20 000 000 fois, en écrivant le résultat dans le fichier bigfile. Si tous vos caractères sont ASCII, alors chacun est un octet, alors calculez correctement en fonction de ce que vous voulez écrire ...

Votre processeur peut appartenir. Je manque de RAM si j'essaie de faire plus de 10 000 000 de lignes ...

Je lance un grille-pain cependant

Zanna
la source
OP veut traiter les octets, pas les lignes.
heemayl
@heemayl bien sûr, votre réponse est meilleure, mais j'ai (vaguement) expliqué comment calculer le nombre de lignes à utiliser pour obtenir les octets souhaités, donc je ne pense pas que ma réponse soit totalement inutile
Zanna
4
@heemayl qu'est-ce qui vous rend si sûr que l'OP veut des octets? La question indique essentiellement que le PO souhaite un fichier volumineux. La taille spécifique est très vague (2-4 Go), donc je doute vraiment qu'il y ait une limite d'octets spécifique à l'esprit.
terdon
1
@heemayl oui, mais c'est très, très vague. Ma compréhension est que l'OP veut juste un gros fichier et ne se soucie pas d'une taille exacte. Sinon, ils auraient donné une taille au lieu d'une aussi vaste gamme de tailles.
terdon
1
@cat ikr! <3python <3
Zanna
9

Perl a l' xopérateur astucieux :

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

Donc, comme solution simple, vous pourriez simplement écrire votre ligne quelques millions de fois. Par exemple, cette commande a créé un fichier 3G:

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

Si vous devez spécifier une taille exacte (2 Gio dans ce cas), vous pouvez faire:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file
terdon
la source
Si vous êtes patient, vous pouvez utiliser des opérateurs Perl 6 sympas, sauf que Perl 6 est beaucoup, beaucoup, beaucoup, beaucoup plus lent: D
cat
@cat est-ce vraiment? Je n'ai pas touché du tout 6, mais j'avais supposé qu'il aurait juste tous les bienfaits et les extras OO. Une idée pourquoi c'est plus lent?
terdon
1
Mon commentaire était plutôt clair, mais j'ai trouvé au début de cette année que Perl 6 est assez lent, par rapport à Python 3 qui est canoniquement beaucoup plus lent que Perl 5 (que je n'ai pas testé). Le travail est axé sur les fonctionnalités et l'exactitude, pas encore sur les performances, mais il a été répertorié comme un objectif pour 2015. De plus, Perl 6 est-il assez rapide pour moi? .
cat
(D'un autre côté, la liste des fonctionnalités est pour le moins impressionnante .)
cat
7
  • Mettez l'ensemble de mots à répéter dans un fichier par exemple source.txt. Obtenez la taille du source.txt, en octets par exemple par:

     stat -c '%s' source.txt
    
  • Décidez de la taille du fichier de destination, par exemple destination.txt, 2 Go ou 4 Go ou autre. Convertissez la taille en octets.

  • Divisez la taille du fichier de destination par la taille du fichier source. bashne peut pas faire d'arithmétique en virgule flottante, mais ce n'est pas nécessaire dans ce cas.

  • Utilisez une forconstruction pour répéter une cat source.txtopération les temps de résultat de division. Ce serait approximativement le plus proche de la taille du fichier de destination que vous pouvez obtenir par répétition. La sortie de l'opération est enregistrée dans destination.txt.

Par exemple, en supposant que le source.txtest de 30 octets et que nous voulons créer un fichier de 2 Go, nous avons besoin de:

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

Ici, je fixe la limite supérieure ((16777216/30))au moment de l'initialisation; vous pouvez obtenir le résultat et le mettre ici aussi.

L'opération prendrait un certain temps; plus la taille est grande source.txt, moins il faudra de temps.

heemayl
la source
1
N'est-ce pas ouvert et fermé destination.txtune fois pour chaque itération de la boucle?
Rétablir Monica - ζ--
@hexafraction Duh, corrigé.
heemayl
6

Vous pouvez également utiliser une whileboucle.

Exemple: Contenu de foo.txt(Ceci est votre source):

foo
bar
foobar

bar.txtest vide (il s'agit de votre fichier cible). Vous pouvez maintenant exécuter la boucle suivante pour écrire le contenu de foo.txtplusieurs fois dans bar.txt:

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

Explication:

  • stat --format "%s" bar.txtaffiche la taille bar.txten octets.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] les actions suivantes seront répétées jusqu'à ce que la taille cible (dans ce cas 150 octets) soit atteinte.
  • cat foo.txt >> bar.txtajouter le contenu de foo.txtàbar.txt
Wayne_Yux
la source
4

d'abord tirer la commande:

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

va créer un fichier sur le chemin de taille bs * compter les octets aléatoires, dans notre cas 2048 * 10 = 20Kb. qui peut être changé selon l'exigence.

cat - > file.txt

Cette commande redirige STDIN vers un fichier, vous devrez donc entrer deux lignes, puis appuyez sur Ctrl + D. Ensuite, vous devrez exécuter la commande suivante:

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

Où n est un entier. Cela créera un fichier contenant 2 ^ (n + 1) lignes, en dupliquant vos deux lignes d'origine. Donc, pour créer un fichier avec 16 lignes, vous feriez:

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

Voici quelques chiffres supplémentaires pour vous aider à démarrer:

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
la source
2
OP veut traiter les octets, pas les lignes.
heemayl
OP conserve également la ligne d'adaptation pour remplir le fichier. et ma première commande a déjà créé un fichier selon les octets de mémoire requis.
Avani badheka
@heemayl, le caractère de nouvelle ligne occupe toujours un octet, comme mon commentaire précédent. C'est un personnage légitime. Cependant, le PO a spécifié des mots , Avani, donc je ne pense pas que votre technique / dev / urandom réponde à leur question.
Mike S
Cela dépend de / dev / urandom, que vous essayiez des octets aléatoires. Même vous pouvez choisir vos propres fichiers qui contiennent autant d'octets de données.
Avani badheka
4

Les FIFO sont probablement ce que vous recherchez. Au lieu d'appeler votre programme avec un fichier donné, vous pouvez lui lier le résultat d'une commande shell via la sous- substitution de processus et le programme verra sa sortie sous forme de fichier en clair. L'avantage ici est que vous n'êtes plus limité par votre espace disque, vous pouvez donc atteindre des tailles de fichiers qui seraient impossibles autrement, tant que votre programme n'a pas besoin de tamponner tout le fichier en premier et qu'il peut simplement l'analyser ligne par ligne. Par exemple, en utilisant la réponse de @hobbs pour générer du contenu:

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

Cela me donne un fichier de 95 gigaoctets (selon wc) sans frais dans l'espace disque dur et à peine n'importe quelle RAM, juste assez pour tamponner ce que la commande retourne avant qu'elle ne soit lue. C'est à peu près aussi "infiniment" que vous allez en avoir.

Santo Guevarra
la source