awkスクリプトでifとシェル変数を使用する

awkスクリプトでifとシェル変数を使用する

次のファイルからデータをインポートしようとしています。

  6   6   1   0
  0.1166667E+02  0.4826611E-09  0.4826611E-09  0.3004786E-09  0.5000000E-15
  1.000000000000000E-004
  CAR 
 system-001                       
     10.51965443    -34.96542345  301      1.95329810      1.00000000
-15.558  0.1631E+01  0.1597E+02
-15.407  0.1661E+02  0.1779E+02
-15.255  0.4253E+01  0.1990E+02
-15.104  0.0000E+00  0.2000E+02
-14.952  0.0000E+00  0.2000E+02
 -3.884  0.0000E+00  0.2000E+02
 -3.732  0.0000E+00  0.2000E+02
 -3.581  0.0000E+00  0.2000E+02
 -3.429  0.0000E+00  0.2000E+02
 -3.277  0.8214E-03  0.2000E+02
 -3.126  0.3543E+00  0.2002E+02
  1.726  0.1019E+01  0.4386E+02
  1.877  0.5581E+00  0.4399E+02
  2.029  0.0000E+00  0.4400E+02
  2.181  0.0000E+00  0.4400E+02
  2.332  0.0000E+00  0.4400E+02
  2.484  0.0000E+00  0.4400E+02
  2.636  0.0000E+00  0.4400E+02
  2.787  0.0000E+00  0.4400E+02
  2.939  0.0000E+00  0.4400E+02
  3.090  0.0000E+00  0.4400E+02
  3.242  0.0000E+00  0.4400E+02
  3.394  0.0000E+00  0.4400E+02
  3.545  0.0000E+00  0.4400E+02
  3.697  0.0000E+00  0.4400E+02
  3.849  0.0000E+00  0.4400E+02
  4.000  0.0000E+00  0.4400E+02
  4.152  0.6271E-01  0.4400E+02
  4.303  0.4520E+01  0.4433E+02
  4.455  0.5040E+01  0.4511E+02

私はいつも行6(この場合は1.95329810)から4番目の列を取得し、次の行の最初の列(この場合は1.877)に最も近い値を探したいと思います。これは参照用であり、一度見つかったら、2番目の列がゼロ以外の次の行(4.152)を抽出したいと思います。

だから私は1.95329810と4.152を出力として取得し、それを引くことで次のようになります。

band_gap=4.152-$fermi_energy

@DopeGhotiの答えを考慮して、ifステートメントで彼のコードを使用しました。

#!/bin/bash
fermi_energy=$(awk 'NR==6 {printf $4}' DOSCAR-62.4902421.st)
awk -f go.awk DOSCAR-62.4902421.st

ファイルの場所go.awk:

BEGIN { 
test=0
}
NF == 3 && test == 0 && $2 != "0.0000E+00" {
   keptvalue=$1
}
NF == 3 && test == 0 && $2 == "0.0000E+00" {
   #print keptvalue
   test=1
}
NF == 3 && test == 1 && $2 != "0.0000E+00" {
   if ( sqrt(($fermi_energy-$1)**2) < 0.5 ) 
   {
       print $1
       test=0
   }
}

しかし、これはawkスクリプトでbash変数を使用する正しい方法ではないと思います。

PD知りたいなら,データは計算を表す状態密度酸化物電子。第1列は電子のエネルギーを表し、第2列は対応するエネルギー準位の電子数を表す。したがって、最も近いレベル以降、「0.0000E+00」ではなく次の値を見つけるとフェルミエネルギー、我々は電子がジャンプして電気を伝導するために必要なエネルギーを計算することができます。 (金属はバンドギャップがゼロなので、電気を伝導するためにエネルギー入力は必要ありません。)

答え1

以下の回答は技術をいくつか変更します。

  1. awk2つではなく1つのプログラムですべてを実行してください。 2番目の実行では、6行目以降の行のみを処理するため、これを行うことができます。

  2. 行6にfermi_energy値を正しく割り当てます。

  3. もう確認する必要がないNF==3のでみんな6行目以降の行はこの基準を満たします。

  4. 変数を削除し、代わりに実行中のタブ間の最小限の違いをtest維持しましょう。この目的のために、最初は最初のテストで失敗することが保証されるとんでもない大きな値を持つ変数を作成します。また、他の変数にもわかりやすい名前を割り当て、テストファイルのすべての行の後に1つの結果のみを印刷します。fermi_energy$1min

  5. 計算的に高価な絶対値テストを、計算的に安価なゼロテストに置き換えます。

  6. 浮動awk小数点科学表記法がサポートされています。たとえば、printfコマンドで format を使用できます。いつものように、詳細についてはそのページやお気に入りの検索エンジンを%Eご覧ください。man

  7. これらの作業はすべて、粒子物理学について全く知らない状態で行われたため、何か間違った情報が得られた可能性があります。なんですか。もしそうなら、少なくともこれがあなたを正しい道に導くことを願っています。

    awk '
        BEGIN  { min=1000 ; jump_energy="INIT" }
        function abs(v) {return v < 0 ? -v : v}
        NR==6 {fermi_energy=$4}
        NR>6 {
            if (jump_energy != 0) {
                this_diff=abs(fermi_energy-$1)
                if (this_diff < min) {
                    min=this_diff
                    energy_level=0
                    jump_energy=0
                    getline
                }
            }
            if (jump_energy == 0  && $2 != "0.0000E+00") {
                energy_level=$1
                jump_energy=$2
            }
        }
        END {
            printf "  Fermi Energy: %f\n  Energy Level: %f\n  Jump Energy: %E\n", fermi_energy, energy_level, jump_energy
        }'
    

答え2

awk 'NR == 6 { fe = $4 }
     NR > 6 && $1 > fe && $2 > 0 { print fe, $1; exit }' file

与えられた入力データに対してfile以下を生成します。

1.95329810 4.152

スクリプトawkは入力の最初の5行を無視します。 6行目では、4番目のフィールドを選択して変数fe(単に「フェルミエネルギー」)に割り当てます。

次に、コードは最初の列の値が増加すると仮定し、最初の列の最初の値がに格納されている値より大きい値に達すると、2番目の列がゼロでない場合にfefeを出力します。最初の列の値列をエクスポートしてエクスポートします。

残念ながら私はそうではありません。完全実際にやろうとしていることの説明がないので、長いコードの断片を理解してください。

関連情報