다른 줄에서 왔어

다른 줄에서 왔어

지속적으로 업데이트되는 파일에서 일부 데이터를 추출하려고 하는데, grep을 사용하여 두 문자열을 필터링하는 방법을 알아냈습니다. 출력은 다음과 같습니다.

!    total energy              =   -9744.24963670 Ry
     convergence has been achieved in 188 iterations
!    total energy              =   -9744.30001681 Ry
     convergence has been achieved in 140 iterations
!    total energy              =   -9744.33953891 Ry
     convergence has been achieved in 155 iterations
!    total energy              =   -9744.36584201 Ry
     convergence has been achieved in 164 iterations
!    total energy              =   -9744.37925372 Ry
     convergence has been achieved in 154 iterations
!    total energy              =   -9744.39185493 Ry
     convergence has been achieved in 153 iterations
!    total energy              =   -9744.39836617 Ry
     convergence has been achieved in 160 iterations

이제 내가 하고 싶은 일은 다음과 같이 이 줄에서 숫자를 추출하는 것입니다. !로 시작하는 줄에서 숫자를 추출합니다. grep 출력의 다음 줄부터 시작하여 열 5의 숫자를 원하고 열 6의 숫자를 원합니다. 다음으로, 이 숫자를 다음과 같이 두 개의 별도 열로 별도의 파일에 쓰고 싶습니다.

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201

나는 awk를 사용하여 모든 grep 결과를 반복한 다음 홀수 행을 보고 열 5를 인쇄한 다음 짝수 행을 보고 열 6을 인쇄할 생각입니다. 하지만 어떻게 해야할지 모르겠습니다.

개별 결과를 개별적으로 변수로 추출해 보았습니다.

var1=$(grep '!' input.file | awk '{print $5}')

그리고

var2=$(grep 'convergence has been achieved' input.file | awk '{print $6}')

그런 다음 파일에 쓰려고 합니다.

echo $var1 $var2 > data.dat

그러나 결과는 예상과 다릅니다.

188                                                                                                                                                                                             
140
155
164
154
153
160 -9744.24963670
-9744.30001681
-9744.33953891
-9744.36584201
-9744.37925372
-9744.39185493
-9744.39836617

위에서 언급한 형식으로 작성하는 방법을 모르겠습니다. 또한 파일이 지속적으로 업데이트되므로 이 코드가 while 루프까지 및 종료 조건과 결합된 것으로 상상됩니다(마지막 부분을 수행하는 방법을 알고 있습니다).

나는 그것을 명확하게 설명했으면 좋겠다!

답변1

해결책:

awk 'v && NR==n{ print $6,v > "result.txt" }/^!/{ v=$5; n=NR+1 }' file
  • <condition1> { <statement> ... }<condition2>{ <statement> ... }- 해당 진술의 조건은 지속적으로 평가됩니다.

  • /^!/{ v=$5; n=NR+1 }- 다음으로 시작하는 라인을 발견하면 !- 5번째 필드 값을 캡처 $5하고 다음 라인 번호를 예약합니다 NR+1(변수에 할당됨 n).

  • v && NR==nv- 첫 번째 키 번호 와 현재 레코드 번호 가 있고 NR필요한 경우"다음 줄 번호" n- 값을 파일로 인쇄result.txt


문서 result.txt내용:

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
154 -9744.37925372
153 -9744.39185493
160 -9744.39836617

답변2

paste자체 솔루션을 사용하려면 결과를 나란히 인쇄하는 명령이 필요합니다 .

paste <(echo "$var2") <(echo "$var1") #or better via 'printf'
paste <(printf '%s' "$var2") <(printf '%s' "$var1")

그러나 간단한 awk명령을 사용하면 다음을 수행할 수 있습니다.

awk '/\!/{C5=$5;getline; print $6, C5 >"output.txt"}' infile

관련 정보