我正在尝试从如下文件中获取数据:
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”值时费米能源,我们可以计算出电子跳跃和导电所需的能量。 (金属具有零带隙,因此不需要能量输入即可导电)
答案1
鉴于缺乏示例输出,这似乎符合您的要求:
awk 'NF == 3 && $2 != "0.0000E+00" { print $1 }' /path/to/input
1.726
1.877
4.152
4.303
4.455
如果您实际上要求的是最后一行的第一个字段,其中第二个字段是不是(数学上)零是接下来是第二个字段的记录是(数学上)零,仅后跟第一个后续记录的第一个字段,其中第二个字段又是不是(数学上)零..这也可以通过相对简单的awk
脚本实现:
$ cat 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" {
print $1
test=0
}
$ awk -f go.awk input
1.877
4.152