Vasp学习专题之常用的批量处理方法

 一些基操

1)ls 命令:列出来当前目录下的所有文件和文件夹

2) cd: 进入文件夹所在的目录

3) pwd:显示当前所在的绝对目录

4) cat 后面加上文件名,就可以在输出里面查看该文件的内容:cat 和文件名之间有空格, 可以是一个,也可以是N个(上一篇我们也提到使用cat命令来生成VASP的POTCAR)

wuxp@ln0:~/yxsun$ cd ex00
wuxp@ln0:~/yxsun/ex00$ cat INCAR -n  #加入-n显示代码行数
     1	SYSTEM=O atom
     2	ISMEAR=0
     3	SIGMA=0.01

5) 对于一个大文件来说,里面有很多行, 用cat就不方便查看了, 我们可以用grep这个命令提取出来所需要的信息

  • 例子1:我们想知道POTCAR中包含的元素,可以用 grep TIT POTCAR 

TIT就是POTCAR中的一个固定的字符,通过提取这个字符,获取我们需要的结果,这里我们知道了 POTCAR中含有O元素

  • 例子2:通过使用:grep ENMAX POTCAR 可以获取POTCAR中O元素的截断能是400 eV

grep 后面提取的字符,最好在文件中是唯一存在的或者只出现几次,否则我们不容易得到期望的结果。大家可以运行下面这两个命令,感受下结果 

grep EMAX POTCAR
grep  PBE POTCAR  
grep  0  POTCAR  #可以是0,也可以是字母O

6) 查看文件的命令还有 more,例如下面的操作:

wuxp@ln0:~/yxsun/ex00$ ls
INCAR  KPOINTS  POSCAR
wuxp@ln0:~/yxsun/ex00$ more INCAR
SYSTEM=O atom
ISMEAR=0
SIGMA=0.01
wuxp@ln0:~/yxsun/ex00$ more POSCAR
O atom in a box
1.0
8.0 0.0 0.0
0.0 8.0 0.0
0.0 0.0 8.0
O
1
Cartesian
0 0 0

 7) 或less,运行less 命令后,会显示文件内容

  • 如果要退出敲一下 q 键即可

  • 如果想编辑文件,再敲一下键盘上的v键,则可以直接进入vim 的编辑界面。退出时和vim的退出方法是一样的

进阶

先来看一段代码:

wuxp@ln0:~/yxsun$ cd ex01
wuxp@ln0:~/yxsun/ex01$ ls
wuxp@ln0:~/yxsun/ex01$ mkdir bigbro #新建文件夹
wuxp@ln0:~/yxsun/ex01$ ls
bigbro
wuxp@ln0:~/yxsun/ex01$ cp bigbro bigbra  #复制文件(夹)
cp: -r not specified; omitting directory 'bigbro'
wuxp@ln0:~/yxsun/ex01$ cp bigbro bigbra -r  #失败后再加-r
wuxp@ln0:~/yxsun/ex01$ ls
bigbra  bigbro
wuxp@ln0:~/yxsun/ex01$ cp ../ex00/  #使用tab,列出ex00中所有文件
INCAR    KPOINTS  POSCAR   
wuxp@ln0:~/yxsun/ex01$ cp ../ex00/* bigbr  #第二次使用tab,列出当前目录下所有以b开头的文件夹
bigbra/ bigbro/ 
wuxp@ln0:~/yxsun/ex01$ cp ../ex00/* bigbra/  #将ex00中的输入文件复制到bigbra这个文件夹中
wuxp@ln0:~/yxsun/ex01$ ls *  #用*来查看某个目录下所有的内容
bigbra:
INCAR  KPOINTS  POSCAR

bigbro:
wuxp@ln0:~/yxsun/ex01$ mv bigbra bigbro  #把bigbra文件移动到bigbro里面
wuxp@ln0:~/yxsun/ex01$ cd bigbro/
wuxp@ln0:~/yxsun/ex01/bigbro$ ls
bigbra
wuxp@ln0:~/yxsun/ex01/bigbro$ mv bigbra/ 0.01  #将bigbra文件夹重命名为0.01
wuxp@ln0:~/yxsun/ex01/bigbro$ ls
0.01
wuxp@ln0:~/yxsun/ex01/bigbro$ cd ../
wuxp@ln0:~/yxsun/ex01$ ls
bigbro
wuxp@ln0:~/yxsun/ex01$ mv bigbro/0.01/ . #将bigbro中的0.01移动到当前目录下(当前目录用.来代替)
wuxp@ln0:~/yxsun/ex01$ ls
0.01  bigbro
wuxp@ln0:~/yxsun/ex01$ rm bigbro/ -fr  #先删掉bigbro文件夹
wuxp@ln0:~/yxsun/ex01$ ls
0.01
wuxp@ln0:~/yxsun/ex01$ for i in {2..9}; do cp 0.01 0.0$i; done  #使用for循环,发现没有加-r,复制的时候出错了
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
cp: -r not specified; omitting directory '0.01'
wuxp@ln0:~/yxsun/ex01$ for i in {2..9}; do cp -r 0.01 0.0$i; done  #加上-r之后,for循环顺利的完成了小目标
wuxp@ln0:~/yxsun/ex01$ ls
0.01  0.02  0.03  0.04  0.05  0.06  0.07  0.08  0.09
wuxp@ln0:~/yxsun/ex01$ for della in {A..Z}; do echo della is $della; done
della is A
della is B
della is C
della is D
della is E
della is F
della is G
della is H
della is I
della is J
della is K
della is L
della is M
della is N
della is O
della is P
della is Q
della is R
della is S
della is T
della is U
della is V
della is W
della is X
della is Y
della is Z

1、mkdir是创建文件夹的一个命令,后面紧跟着你要创建的文件夹的名字。mkdir的使用,有很多窍门,可以百度关键词查找:mkdir 窍门、小诀窍 等等

2、cp这个命令适用于文件以及文件夹的复制

  • 如果复制文件夹的时候,出现cp: omitting directory这个错误,在cp命令后,或者前面命令的结尾加上-r即可
  • 复制文件的时候,不用加-r
  • 学会用tab键来提高自己在终端输入的速度,前两个cp的命令都是tab的结果
    • 第一次使用tab,可以列出来ex01中所有的文件;
    • 第二次使用tab,可以列出来当前目录下所有以b开头的文件夹;
  • 学会用*来查看某个目录下所有的内容

3、mv是转移、重命名文件(夹)的一个命令

4、for循环的使用

1) {2..9} 是为了获取从2到9的所有数字,有以下几点需要注意:

  • for i in {2..9} 和 for i in 2 3 4 5 6 7 8 9 效果是一样的

  • 用的是花括号

  • 2和9中间有两个点 ..

  • 两个点之间没有空格, 2、9 与两个点之间也没有空格

2)大家还可以练习下面这几个命令来看一下效果:echo是打印输出的命令

echo {1..100} 
echo {A..Z}
echo {a..z}
echo {a..z}{1..10}{A..Z}
 

 3)for i in {2..9} : 翻译过来就是:对于从2到9的任意数字 i,i在这里是一个变量;我们给 i 赋值,值的范围是 从2到9;两点需要注意:

  • i 只是个人喜好而已, 你也可以用 for a in XXX ;for b in XXX

  • in 后面是一个 集合,怎么选取这个集合决定了for循环的威力

4) for i in XXX 这个句字后面跟着一个分号,如果没有会出错。分号前后可以有空格,也可以没有,为了让自己写的东西更加直观,建议加上空格

5) do 翻译过来就是:我们要实现什么任务、目的;do 后面跟一个空格,或几个空格

6) cp 0.01 0.0$i -r

  • cp 0.01 把 0.01 这个文件夹复制成 0.0$i 文件夹

  • $i 被替换成for后面变量 i 的值

7) 复制完成后,后面跟着一个分号

8) done 完成任务

那如何利用for循环把INCAR中的SIGMA参数值 SIGMA = 0.01 改成与文件夹对应的数值呢?

5、sed命令

前面我们提到,可以使用vim打开INCAR然后修改SIGMA的参数。除了vim当然还有文本编辑器等其他的工具,但这些工具都有个缺点,就是得把文件打开后才能修改。使用sed命令,不打开文本,直接对里面的内容进行替换操作。

wuxp@ln0:~/yxsun/ex02/0.01$ sed '3s/0.01/0.02/g' INCAR
SYSTEM=O atom
ISMEAR=0
SIGMA=0.02
wuxp@ln0:~/yxsun/ex02/0.01$ cat INCAR
SYSTEM=O atom
ISMEAR=0
SIGMA=0.01

1) 单引号中是我们的操作,3s 表示的是选择第三行,因为我们知道 0.01 在第三行中出现,s 是substitute的缩写
2) 3s 后面跟一个斜杠/用来和后面被替换的内容分开,这里0.01 表示选择第三行的0.01

3) 0.01后面再用一个斜杠,将其和替换后的数字分开(0.01 0.02 0.03 等),表示将0.01替换为斜杠后面的内容

4) 再加一个斜杠,后面的g 代表 global ,意思是全部替换

5) 输入完毕后,我们选择要执行该命令的对象(要替换的文件),也就是当前目录下INCAR 文件

6) 命令的意思就是:我们用sed命令,将INCAR中的第三行的0.01全部替换成0.02

从上面实例中最后的cat INCAR命令结果不难发现,实际上我们并没有将INCAR文件中的0.01替换成0.02。也就是说这个命令只是输出了替换后的结果,但没有更新INCAR文件。那怎么样才可以更新INCAR文件呢? 我们可以这样做:

wuxp@ln0:~/yxsun/ex02/0.01$ sed '3s/0.01/0.02/g' INCAR > INCAR_new
wuxp@ln0:~/yxsun/ex02/0.01$ cat INCAR_new
SYSTEM=O atom
ISMEAR=0
SIGMA=0.02
wuxp@ln0:~/yxsun/ex02/0.01$ mv INCAR_new INCAR
wuxp@ln0:~/yxsun/ex02/0.01$ cat INCAR
SYSTEM=O atom
ISMEAR=0
SIGMA=0.02

注:箭头(>)的意思是我们将命令的输出存到一个新的文件INCAR_new中,再通过mv命令之前的INCAR替换掉

但这样做也太麻烦了,更简单一点,如下:前面例子的INCAR中SIGMA的值已经不是0.01了,我们先从ex02/0.01中复制一个过来

wuxp@ln0:~/yxsun/ex02/0.01$ cp ../../ex01/0.01/INCAR .
wuxp@ln0:~/yxsun/ex02/0.01$ cat INCAR -n
     1	SYSTEM=O atom
     2	ISMEAR=0
     3	SIGMA=0.01
wuxp@ln0:~/yxsun/ex02/0.01$ sed -i '3s/0.01/0.02/g' INCAR
wuxp@ln0:~/yxsun/ex02/0.01$ cat INCAR
SYSTEM=O atom
ISMEAR=0
SIGMA=0.02

sed –i 是sed 的命令和其附加选项, -i 表示直接对源文件进行编辑,也就是说编辑之后源文件被新文件替换掉。因此,使用这个参数的时候要小心,小心,再小心。要格外小心!!!

  • 最保险的做法就是运行前,先对操作的对象进行备份:
  • 其次是先不加 -i 运行下sed命令,确保输出的是正确结果后,然后再加上 -i 运行

sed 是一个非常强大的命令,对于做计算的我们来说,熟练正确地使用sed可以极大的提高我们的工作效率。这个网站列举了一些基本的用法:

http://man.linuxde.net/sed

大家参照着进行练习,也可以百度里面搜索一些其他的 sed 使用技巧


通过sed单个命令进行批量操作:

wuxp@ln0:~/yxsun/ex02$ grep SIGMA */INCAR
0.01/INCAR:SIGMA=0.02
0.02/INCAR:SIGMA=0.02
0.03/INCAR:SIGMA=0.02
0.04/INCAR:SIGMA=0.02
0.05/INCAR:SIGMA=0.02
0.06/INCAR:SIGMA=0.02
0.07/INCAR:SIGMA=0.02
0.08/INCAR:SIGMA=0.02
0.09/INCAR:SIGMA=0.02
wuxp@ln0:~/yxsun/ex02$ sed -i '3s/0.02/0.01/g' */INCAR  #批量修改
wuxp@ln0:~/yxsun/ex02$ grep SIGMA */INCAR
0.01/INCAR:SIGMA=0.01
0.02/INCAR:SIGMA=0.01
0.03/INCAR:SIGMA=0.01
0.04/INCAR:SIGMA=0.01
0.05/INCAR:SIGMA=0.01
0.06/INCAR:SIGMA=0.01
0.07/INCAR:SIGMA=0.01
0.08/INCAR:SIGMA=0.01
0.09/INCAR:SIGMA=0.01

sed + for循环的批量操作:

但我们的目标是,每个文件夹中的SIGMA值与文件夹相同,既然我们知道了sed可以对单个文件进行操作,那么我们也可以结合for循环,来实现一个批量操作的目的。命令如下:

wuxp@ln0:~/yxsun/ex02$ ls
0.01  0.02  0.03  0.04  0.05  0.06  0.07  0.08  0.09
wuxp@ln0:~/yxsun/ex02$ for i in *; do sed -i "3s/0.01/$i/g" $i/INCAR; done
wuxp@ln0:~/yxsun/ex02$ grep SIGMA */INCAR
0.01/INCAR:SIGMA=0.01
0.02/INCAR:SIGMA=0.02
0.03/INCAR:SIGMA=0.03
0.04/INCAR:SIGMA=0.04
0.05/INCAR:SIGMA=0.05
0.06/INCAR:SIGMA=0.06
0.07/INCAR:SIGMA=0.07
0.08/INCAR:SIGMA=0.08
0.09/INCAR:SIGMA=0.09

注意: 

  • 这里我们用的是双引号 “ “ ,sed 命令中你会见到大部分都用单引号 ‘ ‘ 。但如果这里使用单引号,则所有的 0.01 都会被替换成单引号中的i(单引号中的i 是纯字符),因为单引号中的所有内容都会被当做字符来处理,也就是里面是什么就输出什么。使用双引号,则可以读取变量 $i 的值,下面的例子大家一看就知道怎么回事了:
wuxp@ln0:~/yxsun/ex02$ abc=Dr.lightman
wuxp@ln0:~/yxsun/ex02$ echo abc
abc
wuxp@ln0:~/yxsun/ex02$ echo $abc
Dr.lightman
wuxp@ln0:~/yxsun/ex02$ echo '$abc'
$abc
wuxp@ln0:~/yxsun/ex02$ echo "$abc"
Dr.lightman

这里单引号中的内容被原封不动地打印出来了;而双引号可以顺利地把变量调用起来

  • for i in ; 这里指的是当前目录下所有的文件以及文件夹,本例中没有文件,只有从0.01 0.02 0.03 到 0.09 的文件夹;所以 for i in * = for i in 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09

进一步升级sed命令结合for循环。我们借对KPOINTS文件的操作,一方面学习几个小窍门,另一方面回顾上一节的学习内容以及KPOINTS文件。

前面我们学习到,KPOINTS文件只有简单的几行,如下:

K-POINTS  
0  
Gamma
1 1 1
0 0 0 

注意:

  • 第三行的gamma代表的是gamma centered的意思

  • 第四行中的1 1 1 俗称gamma点。很多时候,别人说用gamma点算一下,指的就是1 1 1
  • 除了使用gamma点,我们还可以使用其他的数值,比如2 2 2,3 3 3, 1 2 3 等,数值越大,计算量也就越大,具体的要根据你自己的体系以及组里的计算能力来确定

  • 对于气体分子或者原子的计算来说,也就是把它们放到一个格子的体系,使用gamma点就足够了

本节,我们主要对KPOINTS的文件的第四行进行批量操作,将1 1 1改成 2 2 2、3 3 3 等。首先浏览下面的命令:

wuxp@ln0:~/yxsun$ mkdir ex03 && cd ex03
wuxp@ln0:~/yxsun/ex03$ for i in {1..6}; do cp ../ex02/0.01 ${i}${i}${i} -r; done
wuxp@ln0:~/yxsun/ex03$ ls
111  222  333  444  555  666
wuxp@ln0:~/yxsun/ex03$ cat 333/KPOINTS -n
     1	K-POINTS
     2	 0 
     3	GAMMA
     4	1 1 1
     5	0 0 0
     6	
wuxp@ln0:~/yxsun/ex03$ for i in {1..6}; do sed -i '4s/1 1 1/$i $i $i/g' 
sed: can't read 1/KPOINTS: No such file or directory
sed: can't read 2/KPOINTS: No such file or directory
sed: can't read 3/KPOINTS: No such file or directory
sed: can't read 4/KPOINTS: No such file or directory
sed: can't read 5/KPOINTS: No such file or directory
sed: can't read 6/KPOINTS: No such file or directory
wuxp@ln0:~/yxsun/ex03$ cat 333/KPOINTS -n
     1	K-POINTS
     2	 0 
     3	GAMMA
     4	1 1 1
     5	0 0 0
     6	
wuxp@ln0:~/yxsun/ex03$ for i in {1..6}; do sed -i '4s/1 1 1/$i $i $i/g' 
wuxp@ln0:~/yxsun/ex03$ cat 333/KPOINTS -n
     1	K-POINTS
     2	 0 
     3	GAMMA
     4	$i $i $i
     5	0 0 0
     6	

  • 第三行:我们使用了 mkdir ex03 && cd ex03 这个命令。 && 的作用是将两个命令连起来运行,如果&&前面的命令运行成功,则继续后面的命令。这里我们先运行了mkdir ex03的命令,然后通过cd进入新建的ex03这个文件夹目录下。但如果前面的命令运行不成功,我们还想运行第二个命令,那么可以用 ||这个将两个命令联系起来。百度自己搜索:&& 和 ||的使用,多多练习,可以提高你敲命令的工作效率

  • 我们使用for循环,将ex03中的0.01文件夹复制成111, 222, 333等。这里我们在调用for 循环中的变量i的时候,使用的是。为什么要加花括号呢?这是为了避免i和后面的连在一起,从而导致调用失败

  • 后面的命令中,得到了这样的错误:sed: can’t read 1/KPOINTS: No such file or directory。原因是我们的问价夹中有3个数字,我们需要调用三次,但写i三次,但写i/KPOINTS就会引用一次,导致sed的命令对象不正确

  • 改正之后,我们发现INCAR中的1 1 1 全部被替换成 $i 了。这里是故意犯的错误:将双引号变成了单引号。单引号和双引号的区别,相信大家在练习完之后能大体知道个所以然了

我们没有成功将 1 1 1改成文件夹对应的数字,那该怎么做呢?

wuxp@ln0:~/yxsun/ex03$ for i in {1..6}; do sed -i "s/\$i \$i \$i/$i $i $i/g" $i$i$i/KPOINTS; done
wuxp@ln0:~/yxsun/ex03$ cat 222/KPOINTS
K-POINTS
 0 
GAMMA
2 2 2
0 0 0
  • 这个时候,花括号有或者没有,对命令行影响不大

  • sed 操作的难点在于区别是调用的参数还是要被替换的字符上。例子中我们用一个反斜杠将i是调用的参数还是要被替换的字符上。例子中我们用一个反斜杠将i转义成字符,进而避免将其按照变量来处理。说白了,就是让$ 这个符号变成一个纯文字符号,而不再发挥调用变量的作用。这一部分的知识,大家自行百度搜索:Linux 转义符进行学习

再举个栗子:如果被替换的内容中含有 / , 直接输入则会被认为是分隔符,因此我们需要将其作为分隔符的作用去掉。怎么做呢? 输入\/ (一个反斜杠加单斜杠,中间没有空格),这样的话 / 就会被当成字符来处理了

wuxp@ln0:~/yxsun/ex03$ echo Dr/Lightman
Dr/Lightman
wuxp@ln0:~/yxsun/ex03$ echo Dr/Lightman | sed 's/\//\\/g'
Dr\Lightman
  • 这里我们用了一个|,中文名字叫管道符,它的作用是将前面命令的输出结果传递给后面的命令,用作操作对象。百度自行搜索:Linux 管道符

在本节的操作中,我们可以学到很多知识,私以为对于一个新手来说,这一节的内容难度有些大,需要认真操作,思考,查阅相关的资料。简单总结一下,本节需要掌握的内容有:

  • &&,|| 和 | 的用法

  • ${i} 中什么时候用花括号,什么时候不用

  • sed 中的单引号,双引号的区别;

  • 转义符在字符处理中的作用。

  • 如何避免命令出错,以及出错后改怎么改正。

前面的四点都是死死的基本Linux操作,而最后一点则是考验大家智商的时候。做计算,肯定避免不了会敲错命令,犯各种各样的错误。在避免出错方面,我们要认真掌握命令操作的关键点以及总结前面错误的经验;在错误的改正方面,我们要多多动脑子,及时想办法补救。众多补救的办法中,提前将操作的对象进行备份是最为有效的。比如,在前面例子中,由于在ex03中有备份的文件,即使在ex04目录犯错后,我们大不了全部删除,重新再来一遍。所以,在大家没有进行计算前,先提个醒:一定要时刻牢记备份自己的文件

最终章

前面我们对INCAR,KPOINTS进行了批量操作,这一节,我们介绍对输入文件进行批量操作的最后一部分:POSCAR。前面我们将O原子放到了一个8×8×8 \AA3 的格子里。现在我们要创建不同大小的正方形格子,每个格子边长分别为8、10、12、14、16\AA。重复下面的操作,完成POSCAR的批量练习,并思考这些命令是怎么工作的。

wuxp@ln0:~/yxsun/ex03$ mkdir poscar
wuxp@ln0:~/yxsun/ex03$ ls
111  222  333  444  555  666  poscar
wuxp@ln0:~/yxsun/ex03$ cd poscar/
wuxp@ln0:~/yxsun/ex03/poscar$ for i in $(seq 8 2 16); do cp -r ../../ex02/0.01 ${i}${i}${i}; done
wuxp@ln0:~/yxsun/ex03/poscar$ ls
101010  121212  141414  161616  888
wuxp@ln0:~/yxsun/ex03/poscar$ cat -n 888/POSCAR
     1	O atom in a box
     2	1.0
     3	8.0 0.0 0.0
     4	0.0 8.0 0.0
     5	0.0 0.0 8.0
     6	O
     7	1
     8	Cartesian
     9	0 0 0
    10	
    11	
wuxp@ln0:~/yxsun/ex03/poscar$ for i in $(seq 8 2 16); do sed -i "3,5s/8/$i/g" ${i}${i}${i}/POSCAR; done
wuxp@ln0:~/yxsun/ex03/poscar$ cat -n 888/POSCAR
     1	O atom in a box
     2	1.0
     3	8.0 0.0 0.0
     4	0.0 8.0 0.0
     5	0.0 0.0 8.0
     6	O
     7	1
     8	Cartesian
     9	0 0 0
    10	
    11	
wuxp@ln0:~/yxsun/ex03/poscar$ cat -n 101010/POSCAR
     1	O atom in a box
     2	1.0
     3	10.0 0.0 0.0
     4	0.0 10.0 0.0
     5	0.0 0.0 10.0
     6	O
     7	1
     8	Cartesian
     9	0 0 0
    10	
    11	
  • seq 命令用来打印一系列的数字, 在这个例子中 seq 8 2 16 获取8到16之间的数字,间隔为2; 其中, 8 2 16 三个数字间需要用空格分开;看到这里你会想到之前我们使用的花括号 {},如果间隔是1的话, {1..9} 和 seq 1 1 9 以及 seq 1 9 是一样的; seq 1 9 中省略的是 seq 1 1 9 中间的 1, 因为它是默认值。但是这里我们数字的间隔是2,使用花括号则不能实现我们的目的

  • for 循环的精髓: for i in $(seq 8 2 16);

    提醒1):for循环这部分结束后,要跟一个是分号,不是冒号

    提醒2): $ 和 后面的括号之间没有空格

    大家可以主动把分号改成冒号或者在$后面加个空格,看看会出什么错

    在这里,调用seq 8 2 16这个命令的输出,我们用到了这个组合。它的作用是调用一个命令或者函数的输出,进而转化为循环的对象集合。()这个组合它的作用是:调用一个命令或者函数的输出,进而转化为for循环的对象集合 for i in(seq 8 2 6) = for i in 8 10 12 14 16 

  • 此外,你还会见到一些人使用 ` ` 这个符号(反单引号); `seq 8 2 16` 的效果等于(seq8 2 16)。所以当你见到`不要害怕,因为你知道里面是在调用一个命令或者函数,和(seq8 2 16) 效果是一样的。Linux下面有很多奇奇怪怪的字符,当你知道他们的意思时就见怪不怪了

  • sed 命令,这里我们使用了 sed -i  “3,5s/8/$i/g”

    3,5s 的意思是:选择第三行到第五行中所有的8;然后将它们替换成$i;

为什么说这是 for 循环的精髓呢?

从for循环的语法上看,有两个主要部分:

1)第一个是选取对象,也就是for i in XXX 语句中的 XXX 部分

2)另一个是去执行的动作, do YYY 

对于do YYY 我们根据自己的要求或者要现实的目的,把命令填到YYY这一块就可以了。但是对于前面的集合选取,这就需要脑洞大开了。最简单的是根据自己的任务要求选取合适的范围直接输入,比如 for i in 1 2 3 4 5 

再复杂些,我们使用一个函数,命令或者更高级的命令操作来得到所需范围,如本例中 for i in $(seq 8 2 16)。这个随着计算的进行,你的体会也就越来越深刻

当我们准备计算输入文件,查看计算亦或者整理计算结果时,首先要对这些文件或者文件夹进行选择,即把需要处理的对象放在一起。为了保证for循环变量范围的高效选择,养成一个良好的计算习惯非常重要:那就是保持计算在不同目录下的一致性;也就是目录要规范,文件系统有序而整齐,根据不同的计算等级或者类型进行创建。如果文件夹一个套一个,随意创建,毫无规则可言,那么在用for循环的时候,工作效率就会大大地打折扣。

在这里教给大家另外一个linux 命令:tree 来查看当前目录下的文件夹级别信息,用以给for循环提供合适的变量 (tree 和 tree -d, 尝试下有什么不同)

wuxp@ln0:~/yxsun/ex03$ for i in {1..6};do mv ${i}${i}${i} kpoints; done
wuxp@ln0:~/yxsun/ex03$ ls
kpoints  poscar
wuxp@ln0:~/yxsun/ex03$ cd kpoints/
wuxp@ln0:~/yxsun/ex03/kpoints$ tree
.
├── 111
│   ├── INCAR
│   ├── KPOINTS
│   └── POSCAR
├── 222
│   ├── INCAR
│   ├── KPOINTS
│   └── POSCAR
├── 333
│   ├── INCAR
│   ├── KPOINTS
│   └── POSCAR
├── 444
│   ├── INCAR
│   ├── KPOINTS
│   └── POSCAR
├── 555
│   ├── INCAR
│   ├── KPOINTS
│   └── POSCAR
└── 666
    ├── INCAR
    ├── KPOINTS
    └── POSCAR

6 directories, 18 files
wuxp@ln0:~/yxsun/ex03/kpoints$ tree -d
.
├── 111
├── 222
├── 333
├── 444
├── 555
└── 666

6 directories

可见tree -d只能查看该目录下所有文件夹数目及关系,tree还展示了具体文件的情况

VASP(Vienna Ab initio Simulation Package)是一款用于计算材料结构和性质的第一性原理计算软件。批量提交任务脚本可以用于简化VASP计算的流程,提高计算的效率。下面是一个用于批量提交任务的脚本示例: ```shell #!/bin/bash # 设置计算所需的参数 work_dir="/path/to/your/work/directory" vasp_exec="/path/to/your/vasp/executable" input_files="INCAR POSCAR KPOINTS" job_name="VASP_Job" # 创建任务目录 mkdir -p $work_dir/$job_name cd $work_dir/$job_name # 复制输入文件到任务目录 for file in $input_files do cp /path/to/your/input/files/$file . done # 循环提交任务 for i in {1..10} # 根据需要修改任务数量 do # 创建任务子目录 mkdir -p $i cd $i # 复制输入文件到任务子目录 for file in $input_files do cp ../$file . done # 修改输入文件中的一些参数,如必要 # sed -i 's/param1/param2/g' INCAR # 提交任务 $vasp_exec > vasp.out # 返回上一级目录 cd .. done ``` 以上脚本中,首先设置了计算所需的参数,包括工作目录、VASP可执行文件路径、输入文件列表和任务名称。然后,在工作目录下创建了一个名为`VASP_Job`的目录。接下来,将输入文件复制到任务目录中,并循环提交指定数量的任务。每个任务都在任务目录下创建一个子目录,并将输入文件复制到子目录中。如果需要修改输入文件中的参数,可以使用`sed`命令实现。最后,通过执行VASP可执行文件运行任务,并将输出重定向到`vasp.out`文件中。 需要注意的是,该脚本只是一个示例,具体使用时需要根据实际情况进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值