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
  ...

最初の3行は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のコマンドは、2つの条件と括弧内のワークブロックで構成されています。たとえばcondition{ "actions" }アッ普遍的な文法)。

存在するアッのドル記号は、引数の列$/フィールドの内容を返す演算子です(デフォルトではアッフィールド区切り記号としてタブ/スペースシーケンスを検討してください。

上記の説明によると、例外は$0現在の行/レコードの内容と$1最初のフィールド、$22番目のフィールド、$33番目のフィールドなどを表します。

NRは「これまで見た入力レコードの総数です。」(man awk から) awk が読み取って処理した現在の行番号を示します。

この場合、行3から始めて、4行目ごとに変数を増やします(NR-2)%3==1最初の2行をスキップ)。たとえば、行4を確認しますが、行1から始まるか、同じ操作を実行しますが、行1から始まります。通常、私たちは4行目ごとにチェックしますが、最初の行はスキップします。inc++NR-2(NR-0)%3==1(NR-1)%3==1(NR-#)%3==1#

テストを実行し、awk '(NR-2)%3==1' infileどの行が印刷されているかを確認してください。

2番目のブロックでは、次のようになります。NR>2{ $4=(inc==1)?"LIG":"HOH"; $5=inc }行番号が2より大きい行のフィールド#4と#5の内容のみを更新しますNR>2(最初の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

おすすめ記事