파일에서 다음 문자열을 어떻게 추출할 수 있나요?

파일에서 다음 문자열을 어떻게 추출할 수 있나요?

다음 데이터를 고려하십시오(file.txt에 있다고 가정).

P 5 24 0 0 -9.0786328019999996e+02 9.1141809916739828e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 -3.9196518724924090e+00 2.0727804903086735e+00 -8.9632605571651516e+02 8.9993737237679568e+02 8.0419002445999993e+01 44 0 0 -65 0
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
E 2 -1 -1.0000000000000000e+00 XXX
P 5 24 0 0 -6.7702324192000003e+02 6.8178272642703166e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
E 3 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 YY

즉, 일반적으로 다음과 같은 형태를 갖는다.

P ..
...
P ..
E ..
P ..
...
P ..
E ..

P ..이전 줄만 포함하는 파일을 만드는 것이 가능한지 알려주시겠습니까 E ..?

즉, 파일과

P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0

답변1

사용 grep(다음으로 표시했기 때문에-B), 우리가 사용하는 도구 구현에는 일치하는 행과 일부 이전 행을 추출하기 위한 비표준 옵션이 있다고 가정합니다 .

$ grep -B 1 '^E' file.txt | grep '^P'
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0

이는 두 번 사용됩니다 grep. 먼저 해당 줄로 시작하는 모든 줄과 해당 줄 앞의 모든 줄을 추출한 E다음 P해당 줄로 시작하는 줄을 추출합니다.

그 결과 로 시작하는 줄이 표시되고 P바로 뒤에 로 시작하는 줄이 표시 됩니다 E.

두 번째 출력을 grep파일로 리디렉션하여 일부 파일에 저장합니다.


변수에서 시작하는 줄을 사용하고 기억하고 awk, 볼 때 시작하는 줄을 인쇄하고 지웁니다.PplineE

$ awk '/^P/ { pline = $0 } /^E/ && length(pline) > 0 { print pline; pline = "" }' file
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0

행이 두 개 이상의 연속 행 그룹이 아닌 개별적으로만 발생한다고 가정하고 사용합니다 sed(그렇다면 E최신 행 출력은 한 줄에 한 번 표시됩니다).PE

$ sed -e '/^P/ { h; d; }' -e 'g'  file
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0

이렇게 하면 P모든 행이 예약된 공간에 저장되고 다음 루프가 즉시 시작됩니다. 행이 행이 아닌 경우 예약된 공간에서 P가장 최근에 저장된 행을 가져와서 출력합니다.P

(동일한 가정을 바탕으로 awk위의 코드를 줄여 awk '/^P/ { pline = $0; next } { print pline }' file문자 그대로 로 번역 할 수 있습니다 sed. awk)

관련 정보