我正在尝试从如下文件中获取数据:
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)中获取第四列,然后在以下行中从第一列(在本例中为 1.877)中查找其最接近的值。仅用于参考,在创建之后,我想提取其第二列非零(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在您想知道的情况下,数据代表氧化物电子状态密度的计算。第一列代表电子的能量,第二列代表该能级中电子的数量。因此,在寻找自费米能级最接近的下一个非“0.0000E+00”值时,我们可以计算出使电子跳跃并导电所需的能量。(金属的带隙为零,因此它们不需要能量输入来导电)
下面的答案对您的技术进行了许多更改。
在一个
awk
程序而不是两个程序中完成所有操作。您可以这样做,因为您的第二次运行仅处理第 6 行之后的行:从第 6 行正确分配您的 fermi_energy 值。
不再需要检查,
NF==3
因为第 6 行之后的所有行都满足该标准。消除 variable ,取而代之的是,让我们保留和
test
之间最小差异的运行选项卡。为此,我们将创建一个变量,该变量最初的值非常大,保证第一次测试失败。在测试文件的所有行之后,我们还将为其他变量分配易于理解的名称,并仅打印一个结果。fermi_energy
$1
min
用计算量少的零测试代替计算量大的绝对值测试。
注意
awk
支持浮点科学计数法。例如,在printf
命令中,可以使用格式%E
. 像往常一样,查看man
页面或您最喜欢的搜索引擎了解更多信息。所有这些都是在不了解粒子物理学的情况下完成的,所以我可能有一些不正确的地方。赦免。如果是这样,我希望至少这能让你走上正轨。
对于给定的输入数据,
file
这将产生该
awk
脚本忽略前五行输入。在第六行,它挑选出第四个字段并将其分配给变量fe
(简称“费米能量”。然后代码假定第一列中的值正在增加,并且当这些第一列值中的第一列值达到高于存储在中的值的值时
fe
,如果第二列非零,则打印出第一列中fe
的值列并退出。不幸的是,我不完全理解您较长的代码段,因为没有解释您实际想要它做什么。