프로그램 출력을 파일로 리디렉션할 수 있지만 최대 줄 수는 4줄로 제한됩니다.
./program | save 4 out.txt
는 몇 초마다 계속 ./program
출력(아마도 하나 이상의 라인)을 제공하지만 가장 최근/마지막 라인 4개만 에 저장됩니다 . 이를 수행할 수 있는 프로그램이 out.txt
이미 있습니까 ? save
(아니면 수동으로 만들어야 하나요?)
답변1
입력이 텍스트인 한, 즉 s가 포함되어 있지 않은 한 이는 쉘의 read
내장 함수 에 대해 잘 작동할 수 있습니다 \0NUL
. 파일 작업이 다른 표준 유틸리티에 비해 매우 비효율적인 경우가 많지만 내장 셸을 사용하는 것이 다른 프로세스를 반복적으로 분기하는 것보다 낫기 때문에 이렇게 말하는 것입니다. 어쨌든 효율성을 크게 얻지 못할 것입니다. 왜냐하면 이를 수행하는 유일한 방법은 다음과 같습니다.(내가 아는 한)중복된 출력 파일입니다 open()
- 한 줄당 바이트 수를 확신할 수 없는 경우dd
(아마도 파이프라인의 일부 링크가 이를 보장할 것입니다). 그럼에도 불구하고 다음이 작동합니다.
###seq used for demo###
seq 3 |( set --
while IFS= read -r l
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)
따라서 위와 같이 수행하면 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 %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
... 확장 문제 및/또는 의도하지 않은 문제가 발생할 위험이 없습니다 .
답변2
나는 당신이 실행함으로써 당신이 요구하는 것을 성취할 수 있다고 생각합니다 ./program | tail -n 4 > out.txt
. 그렇지 않다면, 나는 당신이 무엇을 요구하는지 이해하지 못합니다.
답변3
프로그램 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