使用sed与正则表达式修改INCAR参数
时间:2025-07-02 作者:Jiaqi Z.
分类:材料计算
在材料计算的教程中,我们介绍了关于使用Linux的sed命令进行文本替换,其基本格式为sed -i "s/[原字符串]/[替换字符串]/g" [文件路径名]。利用这个方法,我们可以对INCAR文件中的参数进行替换。例如,我们希望将EDIFF从1E-5改成1E-6,可以使用命令sed -i "s/1E-5/1E-6/g" INCAR。
当然,这种方式有一个缺陷:如果INCAR的参数有多个相同的值,如何让命令只修改对应的参数?例如,我们希望修改自旋极化开关ISPIN让其从1变成2,但这个过程可能会使得其他参数(如ISTART)也会发生变化,这显然不是我们想要的结果。
也许……把关键字也加到命令里是可行的……
例如,我们尝试sed -i "s/ISPIN=1/ISPIN=2/g" INCAR,这种方法确实可以只修改ISPIN参数。但是,它忽略了等号两端的空格。对于一些工具(如vaspkit),在生成文件时会带有空格。那么,如果我们直接把空格加上呢?显然也是不行的,因为我们不知道有多少个空格。
注:在INCAR中查看有多少个空格,直接输入在命令中是一种“下策”,因为我们希望将这个功能“普适化”,以便在更多的场景下适用(无论有多少个空格)。甚至,以后可以将其用于for循环或者脚本中(我们后面会给一个脚本的使用例子)
答案是使用正则表达式。
关于正则表达式
在正则表达式中,使用\s符号表示所有空白符,使用\t表示制表符等。显然,空格应当是使用\s表示。但是,如何解决多个空格的问题呢?在正则表达式中,我们可以使用+表示前面的字符出现一次或多次,使用*表示前面的字符出现零次或多次
注意:这里的*不是“通配符”的那个符号。另外,这里的\实际上就是其他大多数程序语言中所表示的“转义字符”
因此,如果我们想要匹配类似于ISPIN = 1这样的字符串,可以用正则表达式写作ISPIN\s+=\s+1(可以自己尝试理解它)。在sed当中使用它,需要使用参数-E(因为像+这种符号属于扩展正则表达式)。综合一下,如果我们希望将ISPIN从1改成2,则可以写作sed -E -i "s/ISPIN\s+=\s+1/ISPIN = 2/g" INCAR
进一步,像上面这样仅使用正则表达式匹配空格算是“中策”,而“上策”则是使用不考虑初始数值,只使用关键字。例如,在设计脚本时,如果在用户使用时还需要提供原来的值,会稍显多余。简单的方法是无论后面的值是多少,直接改成我们想要的数值即可。在正则表达式中,使用\S表示非空白字符(还有\w,表示数字、字母和下划线,二者是不同的,前者范围更大)
如果考虑这种方法,可以将命令写成下面这样:sed -E -i "s/ENCUT\s+=\s+\S+/ENCUT = 600/g" INCAR。这种方式可以将ENCUT设置为600(无论原先的数值是400、520还是800还是其他数值)
一个扩展脚本
我们下面提供一个示例脚本,用户可以直接在当前目录下运行这个脚本,输入要修改的参数和想要的值,脚本会自动修改:
#!/bin/bash
# 修改INCAR参数
read -p "Parameter: " keyWord
read -p "Value: " value
sed -E -i "s/$keyWord\s+=\s+\S+/$keyWord = $value/g" INCAR
echo "Done!"
你可以将这个程序集成到更大的程序中(类似于vaspkit带有菜单功能引导)
上一篇:Roselia Live 「Sei stark」返图
下一篇:non酱の照片1
同分类上一篇:使用lobster进行COHP分析
同分类下一篇:服务器终端程序MobaXterm安装包