Linux awk 命令

      awk是Unix系统中文本处理工具,叫AWK是因为其取了三位创始人 Alfred AhoPeter Weinberger, 和 Brian Kernighan 的Family Name的首字符。

使用awk的方式有:

1.命令行方式
awk [-F field-separator] commands input-file(s) 其中,commands 是真正awk命令,[-F 域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
command 命令需要在花括号中定义。

2.将所有的awk命令插入一个单独文件,然后调用: awk -f awk-script-file input-file(s) 其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

以etc/passwd为例,说明awk使用。

~$ cat passwd.log
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin

各个冒号分隔符含义:

login_name:passwd:UID:GID:user_name:home_dir:shell_path

1. 打印

root@ubuntu:~# awk -F : {print $1, $4} passwd.log
root 0
daemon 1
bin 2
man 12
mail 8
nobody 65534
ym65536 1000
sshd 65534
  • 其中单引号中的被大括号括着的就是awk的语句,注意,其只能被单引号包含。
  • 其中的$1..$n表示第几例。注:$0表示整个行

格式化输出和C类似

root@ubuntu:~# awk -F : {printf "%-8s %-8s\n", $1, $4} passwd.log
root     0       
daemon   1       
bin      2       
man      12      
mail     8       
nobody   65534   
ym65536  1000    
sshd     65534   

2、过滤

a) 过滤条件:GID=65534且shell path = /bin/sh

root@ubuntu:~# awk -F: $4==65534 && $7=="/bin/sh" passwd.log
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh

其中的“==”为比较运算符。其他比较运算符:!=, >, <, >=, <=

b) 显示GID>10的行

root@ubuntu:~# awk -F: $4>10 {print $0} passwd.log
man:x:6:12:man:/var/cache/man:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin

3、内建变量

awk的一些内建变量:

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

打印行号大于6的行的信息:

root@ubuntu:~# awk  -F :  NR > 6 {print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0} passwd.log 
filename:passwd.log,linenumber:7,columns:7,linecontent:ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
filename:passwd.log,linenumber:8,columns:7,linecontent:sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin

4、BEGIN/END

root@ubuntu:~# awk -F: BEGIN {print "longin UID"} {print $1,$3} END {print "END"} passwd.log
longin UID
root 0
daemon 1
bin 2
man 6
mail 8
nobody 65534
ym65536 1000
sshd 114
END

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作

5、字符串匹配

awk使用正则表达式进行匹配

a) 匹配第四列(GID)为65534的行,然后打印1,3列。

root@ubuntu:~# awk -F: $4 ~ /65534/ {print $1,$3} OFS=\t passwd.log 
nobody    65534
sshd    114

//中的内容即为要匹配的内容。

b) 向grep一样匹配root字符串

root@ubuntu:~# awk -F: /root/ passwd.log 
root:x:0:0:root:/root:/bin/bash

c) 匹配root或者ym

root@ubuntu:~# awk -F: /root|ym/ passwd.log 
root:x:0:0:root:/root:/bin/bash
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash

6、if语句

awk中的if语句和C语言类似,使用如下:

if (expression)
{
    statement1;
} 
else if (expression1) 
{
    statement2;
} 
else 
{
    statement3;
}
#注意每条语句以分号
;结尾

 

把第一列匹配root或ym的行放入文件1.txt,其余的放入文件2.txt

awk -F: {if($1 ~ /root|ym/) print > "1.txt"; else print > "2.txt"} passwd.log 
root@ubuntu:~# ls
1.txt  2.txt  passwd.log
root:x:0:0:root:/root:/bin/bash
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
root@ubuntu:~# cat 2.txt 
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin

7、统计

统计当前路径下txt文件大小的和:

root@ubuntu:~# ls -l *.txt
-rw-r--r-- 1 root root  92 2015-02-23 23:11 1.txt
-rw-r--r-- 1 root root 236 2015-02-23 23:11 2.txt
root@ubuntu:~# ls -l *.txt |awk BEGIN{sum=0} {sum += $5} END{print "txt file size is", sum}
txt file size is 328

统计GID=65534的行的个数:

root@ubuntu:~# awk -F: BEGIN{count=0} {if($4==65534) count++} END{print count} passwd.log 
2

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。