Как создать файл из терминала, повторяя набор слов бесконечно?


19

Как создать файл из терминала, повторяя набор слов бесконечно? Мне нужно создать огромный файл для разбора, размером 2-4 ГБ. В настоящее время я вручную копирую вставки строк в тот же файл, чтобы увеличить размер.


1
Мне бы хотелось, чтобы ответ работал со специальными файлами Unix, чтобы он не занимал это место. Это возможно?
Делиссон Хунио

1
Вы имеете в виду что-то действительно бесконечное, как mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Болдевин

Ответы:


50

Есть простой способ повторить строку много раз:

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

приведет к тому, что out.txt будет содержать 10 000 строк со словами «у нас нет бананов».


Чтобы ограничить вывод точным числом байтов, используйте параметр head' -cвместо' -n. Например, это генерирует ровно 10 КБ текста:

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

2
ОП хочет иметь дело с байтами, а не со строками.
Heemayl

4
Чтобы указать ограничение в байтах, просто используйте head -c 10000для 10 КБ вместо 10 КБ head -n 10000строк.
Byte Commander

@ByteCommander да, но это не помешает обрезать вывод в середине строки. Поскольку размер не должен быть точным, я бы просто
вычислил

1
Я согласен, но я не уверен, будет ли это проблемой. ОП не указал, какой метод он хочет, но ваш ответ по-прежнему содержит оба. О, и поздравляю за удвоение вашей репутации сегодня :)
Byte Commander

@ByteCommander да, честно.
Хоббс

10

Я не могу рекомендовать бесконечно повторяющийся текст, но вы можете сделать ~ 2ГБ файл повторяющегося текста с помощью Python, например ...

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

Это напечатает «привет мир» 10 раз и создаст новую строку, и повторите это 20 000 000 раз, записав результат в файл bigfile. Если все ваши символы являются ASCII, то каждый из них по одному байту, поэтому рассчитайте соответственно, в зависимости от того, что вы хотите написать ...

Ваш процессор может быть в собственности. У меня не хватает оперативной памяти, если я пытаюсь выполнить более 10 000 000 строк ...

Хотя я бегу за тостером


ОП хочет иметь дело с байтами, а не со строками.
Heemayl

@heemayl, конечно, ваш ответ лучше, но я (смутно) объяснил, как рассчитать, сколько строк использовать для получения желаемых байтов, поэтому я не думаю, что мой ответ совершенно бесполезен
Zanna

4
@heemayl, почему ты так уверен, что ОП хочет байтов? По сути, вопрос гласит, что ОП хочет большой файл. Конкретный размер очень расплывчатый (2-4 ГБ), поэтому я действительно сомневаюсь, что имеется в виду конкретное ограничение в байтах.
Тердон

1
@heemayl да, но это очень, очень расплывчато. Насколько я понимаю, OP просто хочет большой файл и не заботится о точном размере. В противном случае они бы дали размер вместо такого огромного диапазона размеров.
Тердон

1
@ Cat Ikr! <3 Python <3
Zanna

9

Perl имеет отличный xоператор:

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

Таким образом, в качестве простого решения вы можете написать свою строку несколько миллионов раз. Например, эта команда создала файл 3G:

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

Если вам нужно указать точный размер (в данном случае 2 ГиБ), вы можете сделать:

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

Если вы терпеливы, вы можете использовать классные операторы Perl 6, за исключением того, что Perl 6 намного, намного, намного, намного медленнее: D
cat

@ Cat это правда? Я вообще не трогал 6, но я предполагал, что в нем просто есть все перлы и плюсы ОО. Есть идеи, почему это медленнее?
Тердон

1
Мой комментарий был в основном glib, но я обнаружил в начале этого года, что Perl 6 довольно медленный, по сравнению с Python 3, который канонически намного медленнее, чем Perl 5 (который я не тестировал). Работа сосредоточена на функциональности и правильности, а не на производительности, но она была указана в качестве цели на 2015 год. Кроме того, достаточно ли Perl 6 для меня? ,
кот

(С другой стороны, список возможностей впечатляет, если не сказать больше.)
кошка

7
  • Поместите набор слов для повторения в файл, например source.txt. Получите размер source.txt, в байтах, например:

     stat -c '%s' source.txt
    
  • Определите размер файла назначения, например destination.txt, 2 ГБ или 4 ГБ или любой другой. Преобразовать размер в байтах.

  • Разделите размер файла назначения на размер исходного файла. bashне может делать арифметику с плавающей запятой, но в этом случае она не нужна.

  • Используйте forконструкцию, чтобы повторить cat source.txtоперацию с результатом деления. Это будет ближайший примерный размер файла назначения, который вы можете получить повторением. Результат операции сохраняется в destination.txt.

Например, предполагая, что source.txtэто 30 байтов, и мы хотим создать файл размером 2 ГБ, нам нужно:

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

Здесь я устанавливаю верхний предел ((16777216/30))во время инициализации; Вы можете получить результат и поставить его здесь.

Операция займет некоторое время; чем больше source.txt, тем меньше времени потребуется.


1
Разве это не открывается и не закрывается destination.txtодин раз для каждой итерации цикла?
Восстановите Монику - Sep--

@hexafraction Дух, исправлено.
Heemayl

6

Вы также можете использовать while-loop.

Пример: Содержимое foo.txt(это ваш источник):

foo
bar
foobar

bar.txtпуст (это ваш целевой файл). Теперь вы можете выполнить следующий цикл, чтобы записать содержимое foo.txtнесколько раз в bar.txt:

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

Объяснение:

  • stat --format "%s" bar.txtотображает размер bar.txtв байтах.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] Следующие действия будут повторяться до тех пор, пока не будет достигнут целевой размер (в данном случае 150 байтов).
  • cat foo.txt >> bar.txtдобавить содержимое foo.txtкbar.txt

4

Сначала стреляйте по команде:

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

создаст файл по пути размером bs * count случайных байтов, в нашем случае 2048 * 10 = 20Kb. это может быть изменено согласно требованию.

cat - > file.txt

Эта команда перенаправляет STDIN в файл, поэтому вам нужно будет ввести две строки и затем нажать Ctrl + D. Затем вам нужно будет выполнить следующую команду:

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

Где n - целое число Это создаст файл с 2 ^ (n + 1) строками, дублируя ваши исходные две строки. Итак, чтобы создать файл из 16 строк, вы должны сделать:

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

Вот еще несколько цифр, чтобы вы начали:

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
ОП хочет иметь дело с байтами, а не со строками.
Heemayl

ОП также продолжает копировать строки для заполнения файла. и моя первая команда уже создала файл в соответствии с требуемыми байтами памяти.
Авани Бадхека

@heemayl символ новой строки по-прежнему занимает байт, как и мой предыдущий комментарий. Это законный персонаж. Тем не менее, OP определил слова , Avani, поэтому я не думаю, что ваш метод / dev / urandom отвечает на их вопрос.
Майк С,

Это зависит от / dev / urandom, пытаетесь ли вы использовать несколько случайных байтов. Даже вы можете выбрать свои собственные файлы, которые содержат столько байтов данных.
Авани Бадхека

4

FIFO, вероятно, то, что вы ищете. Вместо того, чтобы вызывать вашу программу с заданным файлом, вы можете привязать к ней результат команды оболочки через подстановку процесса, и программа увидит ее вывод в виде открытого текста. Преимущество здесь в том, что вы больше не ограничены дисковым пространством, поэтому вы можете получить размер файла, который был бы невозможен в противном случае, если вашей программе не нужно сначала буферизовать весь файл, а просто проанализировать его построчно. Например, используя ответ @hobbs для генерации контента:

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

Это дает мне файл объемом 95 гигабайт (в соответствии с wc) бесплатно в пространстве жесткого диска и практически без оперативной памяти, достаточной для буферизации того, что команда возвращает до того, как ее прочитают. Это примерно так же близко к «бесконечно», как вы собираетесь получить.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.