화면의 "부분"을 자주 업데이트하여 로그 파일을 복잡하게 만드는 콘솔 프로그램의 출력을 올바르게 기록하려면 어떻게 해야 합니까?

화면의 "부분"을 자주 업데이트하여 로그 파일을 복잡하게 만드는 콘솔 프로그램의 출력을 올바르게 기록하려면 어떻게 해야 합니까?

매일 밤 cron 작업에서 일부 쉘 스크립트를 실행하는 Java 실행 파일(jar)이 있습니다. 실행 파일은 한 줄씩 순서대로(인쇄 후 인쇄) 로그 문을 "평소대로" 인쇄하지 않지만, 데이터를 처리할 때 상태 데이터가 포함된 한 줄을 인쇄한 다음 "덮어쓰기" 또는 프로세스의 이 부분이 완료될 때까지 이 행을 계속해서 "업데이트"합니다.

예:

일반 프로그램은 다음을 출력합니다.

Program XYZ started..<cr+lf>
processing 1<cr+lf>
processing 2<cr+lf>
processing 3<cr+lf>
im done<cr+lf>

단순한! 출력을 파일로 쉽게 리디렉션할 수 있으며 완료됩니다.

하지만 제가 다루어야 할 프로그램은 다음과 같습니다.

Program XYZ started..<cr+lf>
processing 1<cr>
processing 1 - part a<cr>
processing 1 - part b<cr>
processing 1 - part c<cr>
processing 1 - part d<cr>
<cr+lf>
processing 2<cr>
processing 2 - part a<cr>
processing 2 - part b<cr>
processing 2 - part c<cr>
processing 2 - part d<cr>
<cr+lf>
processing 3<cr+lf>
im done<cr+lf>

하지만 제가 여기서 보여드리는 것보다 훨씬 더 밀도가 높습니다. 따라서 항상 상태 표시줄을 덮어쓰지는 않지만많은처리하는 동안. 따라서 로그 파일에 출력을 리디렉션하거나 추가하는 것만으로는 사람이 쉽게 보고 이해할 수 없는 수백만 개의 화면 업데이트로 로그 파일을 복잡하게 만들기 때문에 여기에서는 그다지 의미가 없는 것 같습니다.

그래서 내 질문은: 프로그램이 30초마다 출력을 로그 파일에 "로그"하거나 "스크린샷"할 수 있도록 하는 방법이나 도구가 있습니까?

답변1

간단히 말해서, 처리할 vt100 이스케이프가 없다고 가정하면 출력을 다음으로 푸시해 볼 수 있습니다.

sed 's/\r$//; s/.*\r//'

또는 awk에 상응하는 것

awk '{ sub("\r$",""); sub(".*\r",""); print}'

그러나 이는 캐리지 리턴이 분명히 줄 바꿈이 아니기 때문에 sed 또는 awk가 매우 긴 줄을 처리할 수 있다고 가정합니다. 또한 캐리지 리턴은 커서를 줄의 시작 부분으로만 이동하지만 해당 줄의 내용을 삭제하지는 않습니다. 따라서 엄밀히 말하면 \r\r\n예제에서는 이전의 긴 줄을 유지해야 합니다.

tr '\r\n' '\n\001'유효한 긴 줄을 처리하려면 개행 문자로 변환을 사용하는 \r동시에 개행 문자를 control-a와 같이 데이터에 없는 다른 문자로 변환할 수도 있습니다.

RS='\r'또는 awk에서 허용하는 경우 Change awk의 입력 레코드 구분 기호를 사용할 수 있습니다. 그러면 다음과 같은 스크립트가 제공됩니다.

awk -v RS='\r' '
{ if(sub("\n","")){print last;last=""}
  if($0!="")last = $0
}'

답변2

나는 둘 중 하나를 사용합니다script2log(단순) 또는 vile-pager(vi는 emacs처럼) 이런 일을 위해서요. 이 스크립트는 위의 유형의 재입력과 백스페이스/재입력을 처리합니다. 명령줄 편집과 같은 커서 이동을 처리하려면 이와 같은 간단한 스크립트만으로는 충분하지 않습니다. 그러나 스크립트는 ANSI 스타일 이스케이프 시퀀스를 제거합니다.

이것스크립트 사용법sed. 이것은 단지 sed 명령입니다:

        # 일반 ANSI 시퀀스를 다듬은 다음 OSC 시퀀스를 다듬고 백스페이스합니다.
        # 시퀀스, 후행 CR, 마지막으로 쿵쿵거리는 부분
        # 좋아요.
        #
        # 아직 처리할 수 없는 흥미로운 상황이 몇 가지 있습니다.
        # 그러한 스크립트를 사용하십시오. 예를 들어:
        #CSI K (클리어 라인)
        # 줄 내에서 커서를 이동합니다.
        sed\
                -e 's/[[][?]\{0,1\}[;0-9]*[@-~]//g' \
                -e's/[]][^]*//g'\
                -e's/[]][^]*\\//g'\
                -e ': 루프; s/[^]\(.\)/\1/g;
                -e's/*$//g'\
                -e 's/^.* //g' \
                -e's/[^[]//g'

POSIX가 아닌 확장에 의존하지 않고 리터럴 이스케이프 문자를 포함합니다.

추가 자료:

관련 정보