:D 获取中...

1 AWK的输出

1.1 简单输出

$ netstat|head -5|awk '{print $1, $4}'
Active (w/o
Proto Local
tcp amd10:34315
tcp amd10:49829
tcp amd10:47962

$ echo "bbbb ccc"| awk '{print $1}'
$ cat a.dat|awk '{print $1, $4}' 
$ awk '{print $1, $4}' a.dat 
  • 其中单引号中的被大括号括着的就是awk的语句,注意,其只能被单引号包含(gawk for windows 是双引号)。
  • 其中的$1..$n表示第几例。注:$0表示整个行

1.2 格式化输出

  • 和C语言的printf没什么两样
  • 注意换行符\n
$ netstat|head -5|awk '{printf "%-8s %-8s %-8s %-12s %-22s %-10s\n",$1,$2,$3,$4,$5,$6}'  
Active   Internet connections (w/o servers)  
Proto    Recv-Q   Send-Q   Local        Address                Foreign  
tcp      0        0        amd10:45977  amd200:ssh             TIME_WAIT    
tcp      0        0        amd10:54689  amd40:ssh              TIME_WAIT  
tcp      0        0        amd10:54688  amd40:ssh              TIME_WAIT  

2 内建变量

变量 含义
$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

3 分隔符

  • -F 指定输入字段分隔符
  • 多个分隔符用[]
$  awk  'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd |tail -2
chenn 624 /home/chenn
yanm 625 /home/yanm

$  awk  -F : '{print $1,$3,$6}' /etc/passwd |tail -2
$  awk  -F [:/] '{print $1,$3,$6}' /etc/passwd |tail -2

$  awk  -F : '{print $1,$3,$6}' OFS="\t" /etc/passwd| tail -2
chenn   624     /home/chenn
yanm    625     /home/yanm

4 记录过滤

4.1 比较运算

  • 比较运算符有:==,!=, >, <, >=, <=
  • 内建变量NR(行号),NF(列数),$NF(最后一列)
$  netstat|head -5|awk '($3==0 && $6=="TIME_WAIT")'
tcp        0      0 amd10:53270                 amd40:ssh                   TIME_WAIT
tcp        0      0 amd10:53271                 amd40:ssh                   TIME_WAIT
tcp        0      0 amd10:53272                 amd40:ssh                   TIME_WAIT


$  netstat|head -5|awk '($3==0 && $6=="TIME_WAIT")||NR==1'
Active Internet connections (w/o servers)
tcp        0      0 amd10:53666                 amd36:ssh                   TIME_WAIT
tcp        0      0 amd10:55245                 amd30:ssh                   TIME_WAIT
tcp        0      0 amd10:58951                 amd200:ssh                  TIME_WAIT

$  netstat|head -5|awk 'NF==6'
$  netstat|head -70|awk '($2>0)'
$  netstat|head -5|awk '($3==0 && $NF=="TIME_WAIT"){print $1} ' 
$  netstat|head -5|awk '($3==0 && $6 ~/TIME_WAIT/){print $1} ' 
$  netstat|head -5|awk '($3==0 || $6 ~/TIME_WAIT/){print $1} ' 
$  netstat|head -5|awk '{if($3==0 || $NF ~/TIME_WAIT/){print $1;}else{print $2;}} '

4.2 字符串匹配

  • ~ 表示模式开始。/ /中是模式。这就是一个正则表达式的匹配。
  • 多个匹配 /aa|bb/
  • 模式取反 !~
$ awk '/muyw/' /etc/passwd   #类似grep 
muyw:x:601:500::/home/muyw:/bin/bash

$ awk '{if($0~/muyw/){print $0}}' /etc/passwd
$ awk '{if($0!~/muyw/){print $0}}' /etc/passwd
$ awk '!/muyw/' /etc/passwd   #类似grep 

5 拆分文件

  • awk中>是追加
$ netstat | head -10| awk '(NR>2){print >$6}'
$ cat TIME_WAIT
tcp        0      0 amd10:39076                 amd200:ssh                  TIME_WAIT
tcp        0      0 amd10:39698                 amd38:ssh                   TIME_WAIT
tcp        0      0 amd10:40589                 amd40:ssh                   TIME_WAIT
tcp        0      0 amd10:32911                 com8:ssh                    TIME_WAIT
tcp        0      0 amd10:56451                 amd10:46701                 TIME_WAIT
tcp        0      0 amd10:41556                 amd10:46701                 TIME_WAIT
tcp        0      0 amd10:47849                 amd10:46701                 TIME_WAIT
tcp        0      0 amd10:38192                 amd201:ssh                  TIME_WAIT

$ netstat | head -10| awk '(NR>2){print $2,$3 >$6}'
$ netstat | head -10| awk '(NR!=1){if($6 ~/TIME|ESTABLISHED/) {print $0> "1.txt";}else if($6 ~ /LISTEN/) {print > "2.txt";}else {print  $0> "3.txt";}}'

$ netstat | head -10| awk '(NR!=1){
if($6 ~/TIME|ESTABLISHED/) {print $0> "1.txt";
}else if($6 ~ /LISTEN/) {print > "2.txt";
}else {print  $0> "3.txt";}}'

6 统计及数组

  • 大小统计
$ ls -l *.dat|awk '{sum+=$5} END{print sum}'
715
$ ls -l *.dat| awk 'BEGIN{sum=0}{sum=sum+$5}END{print sum;}'
  • 类别统计
$ netstat | head -10 |awk '(NR!=1){a[$6]=a[$6]+1;} END {for (i in a) print i ", " a[i];}'
Foreign, 1
TIME_WAIT, 8
  • 内存统计
muyw     31990  0.0  0.0  65604   984 pts/5    R+   13:54   0:00 ps aux
$ ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
rpc, 580KB
gaot, 18236KB
tianxx, 7668KB
muyw, 10316KB
apache, 62504KB

7 变量引入

  • -v 引入变量
  • ENVIRON 环境变量
$ x=5
$ y=10
$ export y
$ awk -v val=$x 'BEGIN{print val,ENVIRON["y"],'${x}'}'

8 AWK脚本

在上面我们可以看到一个END关键字。END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思,语法如下:

  • BEGIN{ 这里面放的是执行前的语句 }
  • END {这里面放的是处理完所有的行后要执行的语句 }
  • {这里面放的是处理每一行时要执行的语句}

学生成绩表:

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

#: 可以增加变量 nstudent

9 Homework for Students

9.1 结构转换

  • CONTCAR与xyz互转
  • CONTCAR转cif
  • Guanssian的log文件转xyz
  • 结构相似性判断(USR指纹识别)
  • mol文件转xyz
  • pdb文件转xyz

9.2 结构搜索

  • Basin-hopping
  • Minima-hopping
  • 遗传算法

9.3 输出结果处理

9.3.1 Gaussian输出文件

  • 提取能量、收敛判据
  • 提取分子轨道系数
  • 提取NBO成键信息,如电荷、键级等
  • 提取TDDFT光谱数据
  • 计算键长及径向分布函数
  • 键长RMSD,MAXD

9.3.2 CP2K输出文件

  • 计算键长及径向分布函数
  • 键长RMSD,MAXD

9.3.3 VASP输出文件

  • EIGENVAL抽取数据绘制能带图
  • PROCAR抽取数据绘制能带图
  • DOS数据抽取

9.4 数据处理

  • DOS数据Gaussian展宽
  • DOS数据Lorentz展宽