캐리지 리턴으로 터미널을 스팸하는 출력 리디렉션

캐리지 리턴으로 터미널을 스팸하는 출력 리디렉션

초당 수백 줄 정도의 매우 자세한 출력을 생성하는 명령이 있습니다. 그러나 이 명령은 \r진행률 표시줄과 유사한 방식으로 이전 출력 줄을 덮어쓰는 데 사용됩니다. 때때로 현재 출력 라인을 "굽는" 터미널에 개행 문자를 씁니다.

이 출력을 파일로 리디렉션하면 수백 메가의 출력이 표시됩니다. 캐리지 리턴이 발생할 때 '덮어쓰기'되는 대신 각 줄이 파일에 기록됩니다.

나는 이것이 예상되는 동작이며 이를 해결하는 한 가지 방법은 프로그램을 더 똑똑하게 만들고 파일로 리디렉션되고 이 대화형 상태를 인쇄하지 않는다는 것을 인식하는 것임을 이해합니다. 하지만 이 프로그램을 수정할 수는 없습니다.

최종 출력 파일의 결과가 터미널에서 대화형으로 실행했을 때 볼 수 있는 것과 동일하도록 이 출력을 파이프/필터링할 수 있는 방법이 있습니까?

난 노력 했어:

spammy_cr_command | uniq

... 없는 것과 동일하게 출력됩니다.uniq

그리고 또한:

spammy_cr_command | sed '/\r/d'

... 개행 문자도 포함하는 "구운" 줄을 삭제합니다.

답변1

cmd | sed -e 's/.*\r//' > file

이렇게 하면 캐리지 리턴 뒤에 오는 각 줄의 모든 텍스트가 아무것도 바뀌지 않고 마지막 캐리지 리턴 뒤의 줄 부분만 남게 됩니다. 이것은 아니다필연적으로하지만 터미널에 남아 있는 것과 동일하지만 대부분의 경우 거의 근사치입니다.


특히, 한 줄이 그 후속 줄보다 긴 경우는 처리되지 않습니다. 이 프로그램은 잘못된 결과를 제공합니다.

printf 'abcdefg\rxyz\n'
printf '123456789\r\nxyz\n'

왜냐하면 눈에 띄게 뒤에 남겨질 것은

xyzdefg
123456789
xyz

하지만 sed삭제되지 않은 모든 문자도 건너뛰고

xyz

xyz

프로그램이 그렇게 작동하는지 여부를 확인할 수 있습니다. 진행률 표시줄 등이 커서를 왼쪽 가장자리에 두는 것은 드문 일이 아니며, 이로 인해 원하는 결과가 나오지 않을 수 있습니다.

답변2

매우 원시적인 TTY-37 출력의 경우 이 명령은 M. Homer의 답변에서 언급된 col문제 없이 이 문제를 해결합니다 . sed(간단한 TTY-37 출력이 아니고 터미널 이스케이프 및 제어 시퀀스를 포함하는 출력의 경우 작업 도구도 아니지만 Stack Exchange에는 다음과 같은 Q&A가 있습니다 col.sed저것벌써 거의 8년째.)

%(
printf 'abcdefg\rxyz\n'
printf '123456789\r\nxyz\n'
) | 열 -b
xyzdefg
123456789
xyz
%

답변3

GNU awk를 사용하면 덮어쓰기 동작에 더 가까운 작업을 수행할 수 있습니다.

BEGIN { 
  RS = "[\r\n]"                   # split records on either CR or LF
  a = ""                          # variable to save the text for overwriting
} 
{
  a = $0 substr(a, 1 + length)    # save current line, add trailing part of saved text
} 
RT ~ /\n/ {                       # LF, time to print and reset
  print a;
  a = ""
}

Michael Homer의 예를 사용하면 다음과 같습니다.

~ awk 'BEGIN { RS="[\r\n]" } {a = $0 substr(a, 1 + length)} RT ~ /\n/ {print a; a=""}' foo
xyzdefg
123456789
xyz

해당 레코드의 정규식 RT과 일치하는 레코드 구분 기호 텍스트가 포함된 변수 에는 GNU awk가 필요합니다 .RS

관련 정보