SOS 문제입니다. 교수님은 전직 박사후 연구원(나에게 그것이 어떻게 작동하는지 설명해 주셨던)이 우리에게 물려준 장기 실행 시뮬레이션 코드의 출력을 가져오라고 요청했습니다.
몇 가지 작은 테스트를 실행했는데 모든 것이 잘 작동했습니다. 그런 다음 약 한 달 전에 전체 시뮬레이션을 시작했고 그 이후로 지속적으로 실행해 왔습니다. 그러나 불과 몇 분 전에 일부 메모리 문제로 인해 포맷된 테이블 출력을 디스크에 쓰기 전에 프로그램이 충돌했습니다.
다행히 중간 결과의 터미널 에코를 활성화하고 롤백 기록을 큰 값으로 설정했습니다. 롤백 모드로 전환하고 전체 터미널 덤프를 텍스트 파일에 복사하고 백업 복사본을 만들어 출력의 일부를 복구했습니다.
이제 이 터미널 출력은 매우 장황합니다(디버깅 목적으로 의도적으로 그렇게 함). 아래는 복구된 터미널 출력 텍스트 파일의 스냅샷입니다(라고 부르겠습니다 terminal_output.txt
).
1 Linear search iteration no. 1 begins: Attempting to blah blah with 1 ...
2 blah blah
3 blah
4 blah blah blah
5 lorem ipsum
.........
........
75 Success with 128 blah ....
76 blah blah
77 blah blah
78 result_flag: 1, exit_reason: 6
79 blah
80 Completed optimal computation with T_init = 25.00 degC & T_sink = 35.00 degC
그러면 이 정확한 패턴이 반복됩니다. 예를 들어,
81 Linear search iteration no. 2 begins: Attempting to blah blah with 1 ...
82 blah
......
95 Success with 307 blah ....
......
......
100 Completed optimal computation with T_init = 30.00 degC & T_sink = 40.00 degC
내 요구 사항은 다음 정보를 추출하여 다음과 같은 표 형식 출력을 생성하는 것입니다.
25 35 128
30 40 307
...........
...........
T_init
즉, 첫 번째 열과 두 번째 열은 각각 과 에 해당하는 값에서 , T_sink
로 시작하는 행에서 나옵니다 Completed
. 세 번째 열은 처음부터의 행 값입니다( 도움이 된다면 Success
항상 5행 앞으로 ). Completed
열 사이에는 공백, 탭, 쉼표 등 모든 구분 기호가 허용됩니다.
grep
, 심지어 sed
와 같은 표준 *nix 유틸리티를 사용하여 awk
로컬에서 이 작업을 수행 하고 싶습니다 vi/vim
. 파이프라인으로 연결된 단일 라인이나 bash
함께 연결된 스크립트가 작동합니다. 필요하다면 다른 스크립트 언어 python
도 사용할 의향이 있습니다.perl
답변1
본질적으로 원하는 부분을 캡처하고 원하지 않는 부분을 폐기하는 문제입니다. 예를 들어, sed
정수 값을 캡처 하고 (를 사용하여 Success
예약된 공간에 복사 할 수 있습니다.시간), 검색하고 추가합니다(G)를 다음 줄에 캡처된 번호로 변환합니다 Completed
.
sed -nE \
-e '/Success/ {s/.* ([0-9]+).*/\1/; h;}' \
-e '/Completed/{G; s/.*T_init = ([0-9]+)\.00 degC & T_sink = ([0-9]+).*\n/\1 \2 /; p;}
' terminal_output.txt
Perl은 IMHO가 더 읽기 쉬운 표현이 풍부한 구문을 제공합니다.
perl -lne '
our $a = $1 if /Success.*?(\d+)/; print join " ", /(\d+)\.\d+/g, $a if /Completed/
' terminal_output.txt
원하는 출력을 생성
25 35 128
30 40 307
답변2
POSIX 호환 sed
:
grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'
GNU sed
: (적어도 CentOS의 4.2.2에서는 일치하지 않습니다 .
)\n
grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*\n.*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'
Success
및가 포함된 행을 잡고 Completed
두 행(필요한 것보다 더 명시적)에 대해 작업하여 관심 있는 세 필드를 꺼내어 하나의 행으로 정렬합니다.
이렇게 하면 중요한 소수 부분( 여전히 단일 후행 0이 있는 .00
것과 같은 항목 포함)을 유지하면서 모든 숫자가 잘립니다 .12.20
...
Completed
경고 이 줄 중 일부에 또는 가 포함되어 있으면 작동하지 않습니다.Success
답변3
빠른 awk
명령을 사용하면 시작할 수 있습니다.
awk '$2 ~ /Success/{a=$4;next}; $2 ~ /Completed/{b=$8;c=$13;print a,b,c}' terminal_output.txt
Success
행 앞에 여러 행이 오는 경우에는 Completed
작동하지 않습니다 .