초당 수백 줄 정도의 매우 자세한 출력을 생성하는 명령이 있습니다. 그러나 이 명령은 \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