awkを使用して他の列を検索して置換する

awkを使用して他の列を検索して置換する

ファイルを変更しようとしています。

値を見つけて他の列の別の値に置き換えるために使用しますawk

入力する( UiO-66Zr-EH.mof):

unit ntype qqatom
  1  'Zr1'  0.0d0
vibration
0
improper
0
unit ntype qqatom
  2  'H1'  0.0d0
vibration
0
improper
0
unit ntype qqatom
  3  'C25'  0.0d0
vibration
0
improper
0
unit ntype qqatom
  4  'O1'  0.0d0

出力( output):

unit ntype qqatom
  1  'Zr1'  2.222d0
vibration
0
improper
0
unit ntype qqatom
  2  'H1'  3.333d0
vibration
0
improper
0
unit ntype qqatom
  3  'C25'  7.456d0
vibration
0
improper
0
unit ntype qqatom
  4  'O1'  9.99d0

私は次のコマンドを試しました。

awk < UiO-66Zr-EH.mof '$2 ~ /Zr1/ {$3 ="2.222.d0"}1''$2 ~ /O1/ {$3 ="9.99d0"}1''$2 ~ /C25/ {$3 ="7.45d0"}1''$2 ~ /H1/ {$3 ="3.333d0"}1' > output

しかし、それはうまく動作しません。

awk同じフォーメーションを維持しながらこれを実行するために使用できるものはありますか?

答え1

おそらく、2番目の列で正規表現の一致ではなく文字列比較を実行したいと思うでしょう。提供された例を使用してこれを行うには、比較に一重引用符を含める必要があります。これはすべてをシェル引用悪夢にします。これを行うと、次のような結果が得られます。

awk "\$2==\"'Zr1'\" { \$3=\"2.222.d0\" }
     \$2==\"'O1'\" { \$3=\"9.99d0\" }
     \$2==\"'C25'\" { \$3 =\"7.45d0\" }
     \$2==\"'H1'\" { \$3 =\"3.333d0\" }
     { print }" <UiO-66Zr-EH.mof

答え2

ここで最初の問題は、あなたの価値が参照されることです。コマンドを使用して引用符を削除sedし、必要に応じてファイルを処理して再度挿入することをお勧めしますawk。それはまるで

sed "s/'//g" UiO-66Zr-EH.mof | awk '{$2=q $2 q}' q="'" 

上記のトリックは変数を等しく設定qします。一重引用符を使用する簡単な方法は次のとおりです。'q $2 q'$2'awk

スクリプトによると、次の置換を実行したいようです。

$2 is   $3 should be
---------------------
Zr1     2.008.d0
O25     -1.179d0
O1      -0.582d0
C25     -0.121d0
C13     -0.002d0
C1      0.625d0
O29     -0.741d0
H1      0.127d0
H25     0.495d0

もしそうなら、私は次のようにします

$ sed "s/'//g" UiO-66Zr-EH.mof |
   awk 'BEGIN{
        c["Zr1"] = "2.008.d0";
        c["O25"] = "-1.179d0";
        c["O1"] = "-0.582d0";
        c["C25"] = "-0.121d0";
        c["C13"] = "-0.002d0";
        c["C1"] = "0.625d0";
        c["O29"] = "-0.741d0";
        c["H1"] = "0.127d0";
        c["H25"] = "0.495d0";
        }
    {if( $2 in c){$3=c[$2]; $2=q$2q}}1;' q="'" 

説明する

  • まず、sed入力ファイルからすべての一重引用符を削除します。
  • sedの結果は入力に渡されます。awk
  • このBEGIN{}ブロックはファイルを読み取る前に実行されます。連想配列マッピングが設定されています。
  • メインプログラムでは$2それが配列に定義されていることを確認しc、そうで$3あれば配列の対応する値に置き換えます。
  • $2=q$2q一重引用符を元に戻します$2
  • 最後に1;ラインを印刷します。

例を実行したときの出力は次のとおりです。

unit ntype qqatom
1 'Zr1' 2.008.d0
vibration
0
improper
0
unit ntype qqatom
2 'H1' 0.127d0
vibration
0
improper
0
unit ntype qqatom
3 'C25' -0.121d0
vibration
0
improper
0
unit ntype qqatom
4 'O1' -0.582d0

関連情報