2015-11-05 2 views
1

Я пытаюсь разделить выход программы на более мелкие файлы. Это длинная программа, которая выводит свой вывод на stderr, и я хотел бы записывать журналы в ряд небольших файлов, а не в один гигантский файл. Так что у меня есть:Streaming split

program 2>&1 | split -l100 & 

... но, к моему ужасу, я обнаружил, что инструмент split фактически не писать какие-либо файлы на диск, пока входной буфер не заканчивается. То, что я хочу, представляет собой потоковый инструмент, который автоматически копирует свой вход в выходные файлы потоковым способом, не дожидаясь окончания потока источника, что в нашем случае не является необходимым. Я также попробовал параметр -u инструмента split, но он не работает, если вы не выбрали опцию -n, но этот вариант действительно не применим в моем случае, потому что количество сгенерированных файлов может быть произвольно высоким. Есть ли инструмент Unix, который может позволить мне сделать это?

+1

Попробуйте использовать 'awk'. Он может открывать новый выходной файл каждые 100 строк. – Barmar

+0

Почему не 'program 2> & 1 | split -l100 - output_ & ' –

+0

@Barmar Я попробовал подход здесь http://stackoverflow.com/questions/25712730/split-file-by-number-of-lines-and-pattern-in-awk-perl, но он не обладает потоковым эффектом, который я хочу. По-прежнему кажется, что только фиксирует изменения на диске после окончания потока ввода. –

ответ

0

Предложение Barmar, чтобы добавить звонок в fflush() после каждой итерации в скрипте awk, работало для меня. Это было предпочтительнее, когда я вызывал close() на каждый файл, когда это было сделано, поскольку это будет только очищаться, когда каждый файл будет заполнен, в то время как мне нужно поведение, зависящее от строки. Я также должен был сконфигурировать выходной канал для буферизации строк, поэтому команда в конце выглядит так:

stdbuf -oL -eL command 2>&1 | awk -v number=1 '++i>1000 {++number; i=0} {print > "file" number; fflush("file" number)}'