awk를 사용하여 파일에 열 추가 및 변경

awk를 사용하여 파일에 열 추가 및 변경

약 30000줄의 파일이 있습니다.

TITLE      cargas
REMARK   1 File created by GaussView 5.0.9
HETATM    1  O           0       0.957  -0.000  -0.000                       O
HETATM    2  H           0       0.000   0.000   0.000                       H
HETATM    3  H           0       1.197   0.927  -0.000                       H
HETATM    4  O           0      -1.664  -0.019   0.488                       O
HETATM    5  H           0      -2.210   0.327   1.194                       H
HETATM    6  H           0      -2.260  -0.104  -0.257                       H
HETATM    7  O           0       2.189  -2.104   1.321                       O
HETATM    8  H           0       1.559  -1.476   0.968                       H
HETATM    9  H           0       1.764  -2.955   1.216                       H
  ...

이전 파일의 다음 형식을 원합니다.

TITLE      cargas
REMARK   1 File created by GaussView 5.0.9
HETATM    1  O   LIG     1       0.957  -0.000  -0.000                       O
HETATM    2  H   LIG     1       0.000   0.000   0.000                       H
HETATM    3  H   LIG     1       1.197   0.927  -0.000                       H
HETATM    4  O   HOH     2      -1.664  -0.019   0.488                       O
HETATM    5  H   HOH     2      -2.210   0.327   1.194                       H
HETATM    6  H   HOH     2      -2.260  -0.104  -0.257                       H
HETATM    7  O   HOH     3       2.189  -2.104   1.321                       O
HETATM    8  H   HOH     3       1.559  -1.476   0.968                       H
HETATM    9  H   HOH     3       1.764  -2.955   1.216                       H
  ...

처음 세 줄은 LIG로 써야 하고, 다른 모든 줄은 HOH로 써야 합니다. 5열은 1부터 100까지 번호가 매겨져 있으며 각 번호마다 3개의 행이 있습니다.

도움을 주셔서 미리 감사드립니다.

답변1

awk '
    (NR-2)%3==1 { inc++ }
    NR>2        { $4=(inc==1)?"LIG":"HOH"; $5=inc }1' infile

awk명령은 두 가지 조건과 괄호 안의 작업 블록으로 구성됩니다. 예를 들어 condition{ "actions" }(보편적 문법).

존재하다에서 달러 기호는 $인수의 열/필드 내용을 반환하는 연산자입니다(기본적으로필드 구분 기호로 탭/공백 시퀀스를 고려하세요.

위의 설명에 따르면 예외는 $0현재 행/레코드 내용과 $1첫 번째 필드, $2두 번째 필드, $3세 번째 필드 등을 나타냅니다.

NR은"지금까지 본 총 입력 레코드 수입니다."(man awk에서) awk가 읽고 처리한 현재 줄 번호를 나타냅니다.

이 경우 행 3부터 시작하여 4번째 행마다 변수를 증가시킵니다 ((NR-2)%3==1 처음 두 행 건너뛰기). 예를 들어 행 4를 확인하지만 행 1 에서 시작 하거나 동일한 작업을 수행하지만 행 1에서 시작합니다. 일반적으로 우리는 4번째 마다 확인 하지만 첫 번째 줄은 건너뜁니다.inc++NR-2(NR-0)%3==1(NR-1)%3==1(NR-#)%3==1#

테스트를 수행하고 awk '(NR-2)%3==1' infile어떤 줄이 인쇄되는지 확인하세요.

두 번째 블록에서는 다음과 같습니다. NR>2{ $4=(inc==1)?"LIG":"HOH"; $5=inc }행 번호가 2보다 큰 행에 대해 필드 #4 및 #5의 내용만 업데이트합니다 NR>2(처음 두 행은 건너뛰기).

이는 var 값이 여전히 1이 될 $4=(inc==1)?"LIG":"HOH"때까지 필드 #4의 값을 "LIG"로 설정합니다. 그렇지 않으면 "HOH" 값 도 사용합니다 .inc$5=incinc

1마지막으로현재 줄을 인쇄하는 관용어와 항상 참인 조건을 참조하세요.awk 스크립트 끝에 있는 "1"은 무엇을 의미합니까?더 알아보기.


마지막으로 필드 간 의도를 유지하려면 다음을 수행합니다.

awk -F'( )' '
    (NR-2)%3==1 { inc++ }
    NR>2        { $9=(inc==1)?"LIG":"HOH"; $14=inc }1' infile

또는 첫 번째 awk 스크립트 출력을 awk ... |column -t.

관련 정보