Bash脚本获取VASP能带计算数据

由于天天蹲宿舍导致coding能力得到大大加成的我,又把之前用python写的获取vasp能带计算数据的脚本移植到了bash平台,没错,这就是天天蹲在宿舍无事可做的我的日常。要用bash语言实现数据的提取个人感觉是比python要难一些的,关键就是在bash语言里面,浮点数并不能直接计算,而是需要使用awk命令来实现,并且不能使用python的Numpy库,导致一次需要定义多个变量来逐个存储变量,非常麻烦!代码的框架和python版本的实现大同小异,具体可以参考前面这篇文章:使用Python脚本获取VASP能带计算数据。相应的代码已经上传到Github仓库中了,这里是—>传送门。脚本运行需要使用的两个文件是OUTCAR文件和KPOINTS文件,并不需要vasprun.xml文件,这一点与python版本的不同,请注意!
由于代码框架和前面那篇文章框架相似,并且生成的文件结构也类似,因此不再过多介绍,以下是根据脚本导出的数据作的能带图,结果经验证都是无误的:

  • no spin bands:
    nospinbds
  • spin bands:
    spinbds

不再说明代码的结构和用法了,而是想要写一下用bash语言写程序中遇到的几个关键问题,这才是我在做这件事情真正的收获。

1.awk使用

前面已经说过,使用bash语言编程的一个重要问题,就是如何处理浮点数的运算,awk命令可以比较容易地解决这个问题,其有很多内置的函数,功能非常强大,基本所有的浮点数运算都可以解决,使用时先把计算要使用的变量通过管道传递给命令,然后使用,如:

1
2
3
4
5
### 计算sqrt(x^2+y^2)
x=3.5
y=4.2
z=$(echo $x $y | awk '{print sqrt($1*$1+$2*$2)}')
echo $z

在后面的计算表达式处,按照顺序,$1表示第一个变量,$2表示第二个变量,awk默认以空格切分字符串(当然可以改成以其它字符切割字符串)。
配合函数的一些内建变量,还可以实现更加复杂的功能,如需要获取test.txt文件第三行第2个字符串,命令如下:

1
cat test.txt | awk 'NR==3{print $2}}'

其中的传入NR变量的值也可以通过自定义变量传入,对应的命令是:

1
2
line_count=3
cat test.txt | awk 'NR==lc{print $2}' lc=$line_count

2.grep使用

grep是bash语言中内置的一个功能非常强大的文本分析命令,可以抓取文件中特定的字符串,然后将抓取到结果打印出来,基本使用如下:

1
2
# 将test.txt文件中所有包含"hello world"字符串的行打印出来
grep "hello world" test.txt

其中抓取的内容可以配合正则表达式,能实现非常发杂的功能,我在写脚本的过程中只使用了-A参数,它的意思是打印抓取到的行以及其后n行的内容,例如:

1
grep "hello world" test.txt -A 3

以上脚本实现了打印test.txt文本中所有包含"hello world"的行以及其后3行的所有内容,当然这里3也可以用变量代替。

3.sed使用

sed是bash语言内置的文本增删和替换的命令,功能同样非常强大,具体可以参考相关教程,这里我只使用了一个功能:即获取文本中特定行的文本,实现这个功能的命令如下:

1
2
line_count=3
sed -n "$line_count p" test.txt

可以看到这里传入的参数也是之前定义的变量,要注意的是**为了实现这一功能,中间要使用双引号,使用单引号是不行的。**在bash语言中单引号和双引号的功能有差别

4.总结

最后总结一下,bash语言优秀就优秀在灵活的文本处理功能上,但是弱点也很明显,即浮点数计算以及非常少的数据结构上,但是这并不妨碍Linux继续使用它,因为对于操作系统而言,文本的输入和输出才是日常工作,而很少需要处理复杂的计算。