Перенаправить вывод программы в файл с лимитом номера строки

Возможно ли перенаправить вывод программы в файл, но с максимальным лимитом, например, ограничение на четыре строки:

./program | save 4 out.txt 

Программа ./program продолжит выдавать выходные данные (возможно, одну строку или более) каждые несколько секунд, но только 4 последних / последних строки будут сохранены в out.txt . Есть ли программа save которая может это сделать? (или я должен сделать это вручную)

  • Почему я получаю это сообщение всякий раз, когда я открываю терминал?
  • Как регистрировать все события, которые произошли с помощью сеанса SSH?
  • Почему в /var/log/kern.log есть нули?
  • как я могу получить дату и время из первого поля access.log (squid)?
  • 1 (su, sudo), он наводняет записи в / var / log / messages
  • Почему в типичной Linux-системе так много файлов журналов? Почему они не используют один консолидированный журнал db / file и api?
  • Файл журнала Apache - URL-адрес реферера, который не существует
  • Где просмотреть журнал ошибок для уже готовой команды tar tar?
  • 3 Solutions collect form web for “Перенаправить вывод программы в файл с лимитом номера строки”

    Это может быть хорошей задачей для встроенного read оболочки – пока ваш ввод является текстовым, то есть, и не содержит никаких \0NUL . Я говорю об этом, потому что, хотя он часто ужасно неэффективен для работы с файлами по сравнению с другими стандартными утилитами, использование встроенной оболочки, вероятно, будет лучше, чем повторное форсирование другого процесса. И в любом случае вы не получите большой эффективности, потому что единственный способ сделать это (что я знаю) состоит в том, чтобы повторно open() ваш выходной файл – если вы не можете быть уверены в количестве байтов на строку (что может быть гарантировано с несколькими цепями dd s в конвейере, я думаю) . В любом случае будет работать следующее:

     ###seq used for demo### seq 3 |( set -- while IFS= read -rl do set -- "$@" "$l" shift "$(($#>4))" printf %s\\n "$@" >/tmp/4_lines ###demo commands### printf '\n###4_lines CONTENTS###\n' cat </tmp/4_lines printf '###END###\n' ###end demo### done) 

    Поэтому, если я делаю это выше, как написано, это записывается в stdout цикла while:

     ###4_lines CONTENTS### 1 ###END### ###4_lines CONTENTS### 1 2 ###END### ###4_lines CONTENTS### 1 2 3 ###END### 

    Но если я seq 20, например, он печатает выше:

     ###4_lines CONTENTS### 1 2 3 4 ###END### ###4_lines CONTENTS### 2 3 4 5 ###END### 

    … вплоть до …

     ###4_lines CONTENTS### 16 17 18 19 ###END### ###4_lines CONTENTS### 17 18 19 20 ###END### 

    Это будет продолжаться до тех пор, пока входной канал не будет закрыт – просто округляет массив arg и переписывает /tmp/4_lines с содержимым массива каждый раз, когда read строка ввода. Если вы хотите, чтобы строки были в обратном порядке, поэтому первая строка – это последняя строка, в которую вы printf , вы можете изменить строку printf на:

     printf %s\\n ${4+"$4"} ${3+"$3"} ${2+"$2"} "$1" >/tmp/4_lines 

    … который будет печатать как …

     ###4_lines CONTENTS### 1 ###END### ###4_lines CONTENTS### 2 1 ###END### ###4_lines CONTENTS### 3 2 1 ###END### 

    …через…

     ###4_lines CONTENTS### 19 18 17 16 ###END### ###4_lines CONTENTS### 20 19 18 17 ###END### 

    … без риска каких-либо трудностей с $IFS и / или непреднамеренными шагами по расширению.

    Я думаю, вы можете делать то, что вы просите, запустив ./program | tail -n 4 > out.txt ./program | tail -n 4 > out.txt . Если нет, то я не понимаю, что вы просите.

    Программа save может быть примерно такой:

     #include<string> #include<iostream> #include<fstream> #include<cstdlib> using namespace std; int main(int argc,char *argv[]) { if(argc<=2) { cerr << "First param must be a number, second must be a file" << endl; return -1; } int max = atoi(argv[1]); if(max <= 0) return -2; string lines[max]; int cmax = 1; int z = 0; while(true) { getline(cin,lines[z]); ++z; z %= max; ofstream fo(argv[2]); for(int x=0;x<cmax;++x) { fo << lines[(x+cmax-z)%cmax] << endl; } fo.close(); if(cmax<max) ++cmax; } } 

    Компилировать с помощью g++ save.cpp -o save

    Linux и Unix - лучшая ОС в мире.