n개 이상의 라인이 있는 경우에만 파이프 출력

n개 이상의 라인이 있는 경우에만 파이프 출력

나는 종종 일부 헤더 라인을 포함하는 프로세스의 출력을 파악하고 싶습니다. 하지만 grep이 실제 콘텐츠 행을 모두 제거하는 경우 헤더 행을 표시하고 싶지 않습니다. 이렇게 하려면 this 과 유사한 명령이 필요 tail하지만 n 행을 반환하는 대신 다음을 반환합니다.모두행(제목)이 n개 이상인 경우에만 해당됩니다.

동료가 이 작업을 수행하기 위해 작은 Python 도구를 작성했지만 이 작업을 수행하는 데 필요한 모든 컴퓨터에 이를 설치해야 합니다.

표준 도구(아마도 awk?)를 사용하여 이 효과를 얻을 수 있는 짧은 명령줄이 있습니까?

답변1

awk 배열의 첫 번째 줄을 저장 n하고 line 이 보일 때 n + 1, 즉 최소한 한 줄의 데이터를 찾을 때 쓸 수 있습니다.

Awk_N='
FNR <= N { X[FNR] = $0; next; }
FNR == N + 1 {
    for (j = 1; j in X; ++j) print X[j];
    delete X;
}
{ print; }
'

awk -v N=7 "${Awk_N}"

7Awk 부분을 편집하지 않고도 교체할 수 있도록 쉘 공간 변수를 만들었습니다 .

Awk 부분은 파이프라인을 정리하기 위해 작은따옴표로 묶인 여러 줄 셸 문자열 변수로 미리 선언되어 있습니다.

awkgrep 논리를 여기에 포함할 수 있는지 여부도 고려할 수 있습니다.

약간 더 짧은 버전으로 모든 행을 저장합니다.

awk '{ X[NR] = $0 } END { if (NR > 3) for (j = 1; j in X; ++j) print X[j] }'

이렇게 하면 문자 수가 최소화됩니다(가독성이 저하됨).

awk '{X[NR]=$0}END{if(NR>3)for(j=1;j in X;++j)print X[j]}'

답변2

다음은 한 줄입니다 sed(모든 내용을 인쇄한다고 가정하고 최소 4줄이 있으면 n=4).

cmd | sed -e '4,$!{H;1h;d;}' -e '4H;4x'

따라서 변수를 사용하고 싶다면

cmd | sed -e "${n}"',$!{H;1h;d;}' -e "${n}H;${n}x"

이것이 하는 일은 이전 버퍼 n-1의 첫 번째 라인을 저장 하고 패턴 공간에서 제거하므로 아무것도 인쇄되지 않는다는 것입니다... 적어도 한 라인이 수신되지 않는 한, 첫 번째 라인을 이전 공간 에 추가한 다음 버퍼를 변경하면 이제 패턴 공간에 행이 포함됩니다 . 나머지는 자동 인쇄 문제입니다. GNU가 아닌 일부 설정에서는 다음과 같이 작성하고 싶을 수도 있습니다( 이번에는 가정):HdsednHx1n
n=21

cmd | sed '21,$!{
H;1h;d
}
21H;21x'

답변3

헤더 길이가 7줄인 경우 입력 길이가 <= 7이면 제거할 수 있습니다. Perl 또는 (gnu)sed를 사용하십시오.

cmd... | perl -0pe 's/^(.*\n){,7}$//'
cmd... | sed   -zE 's/^(.*\n){,7}$//m'

(기가바이트 입력으로 이 작업을 수행하지 마십시오)

답변4

tee나는 다음을 사용하여 이 문제를 해결 했습니다 wc.

cmd | tee x | [ `wc -l <&0` -gt 3 ] && cat x && rm x

이 예에서는 3줄 이상이면 전체 출력이 인쇄됩니다.

NB1 줄이 3개 이상인지 여부만 알아야 할 때 전체 파일의 줄 수를 세는 것은 과잉입니다.

NB2는 성능을 더욱 저하시켜 임시 파일에 기록합니다. 내가 이해하는 바에 따르면 mkfifo메모리에 저장되지만 명령은 더 길어질 것입니다.

관련 정보