当前位置: 首页 > 范文大全 > 党史学习 >

awk命令学习

时间:2021-11-08 18:14:23 来源:网友投稿

 awk 简介

 一种名字怪异的语言,模式扫描和处理,处理 stream editor 文本流,水流。

 awk 不仅仅是 linux 中的一个命令,而且是一种编程语言,可以用来处理和生成报告。处理的数据可以是一个或多个文件,可以是来自标准输入,也可以通过管道获取标准输入,可以在命令行直接编辑命令进行操作,也可以编写成 awk 程序进行更为复杂的应用。

  学完本章你会了解:

 域(字段)与记录 模式匹配 基本的 awk 执行过程 awk 常用的内置变量(预定义变量)

 awk 数组(工作常用)

 awk 语法:循环,条件 awk 常用函数:print 向 awk 传递参数 awk 引用 shell 变量 awk 编程

 本书涉及的 awk 为 gawk,即 GNU 版本的 awk 版本:

 [root@oldboy ~]# awk --version GNU Awk 3.1.7 Copyright (C) 1989, 1991-2009 Free Software Foundation. [root@oldboy tmp]# cp /etc/passwd ./awkfile.txt

 区域和记录:

 区域 filed:域,区域,字段 记录 record:记录,默认一整行 eg:$1,$2,$3,$NF $0,一整行 每个字段之间的分隔符是由内置变量 FS 控制的,默认是空格或制表符,每行记录的字段数保存在内置变量 NF 中 默认情况每一行内容为一个记录,行分隔是以 RS 变量控制的,这个可以修改 RS==>每个记录读入的时候的分隔符 NR==>行号,记录的数 [root@oldboy tmp]# awk "BEGIN{RS=":"}{print NR,$0}" awkfile2.txt 1 root 2 x 3 0 4 0

 5 root 6 /root 7 /bin/bash 将行分隔符指定为:,注意不是字段,BEGIN 是什么意思? 案例:计算文件中每个单词的重复数量 [root@oldboy tmp]# grep -Eo "[a-zA-Z]+" awkfile1.txt |sort|uniq -c

  1 bash

  4 bin

  1 nologin

  3 root

  1 sbin

  2 x

 [root@oldboy tmp]# sed -ri.bak "s#[:/0-9]# #g" awkfile1.txt 把文件中的冒号和数字全替换成空格,在执行之前先备份成 awkfile1.txt.bak

 [root@oldboy tmp]# awk "BEGIN{RS=" |\n"}{print $0}" awkfile1.txt |sort|uniq -c|sort –rn(指定行分隔符为空格或换行符)

 12

 4 bin

  3 root

  2 x

  1 sbin

  1 nologin

 例:

 [root@oldboy ~]# echo {0..10}

 0 1 2 3 4 5 6 7 8 9 10 [root@oldboy ~]# echo {0..10}|awk "BEGIN{RS=" "}{print $0}" 0 1 2 3 4 5 6 7 8 9 10

 记录小节:

 1、 NR,NF,$数字,配合调试 awk 命令 2、 NR number of record 存放着每个记录的号(行号),读取新行时会自动+1 3、 RS 是记录的分隔符,简单理解就是可以指定每个记录的结尾标志

 4、 可以用 RS 替换\n 5、 RS 的作用就是表示一个记录的结束 6、 FS 标识着每个区域的结束 字段小结:

 1、$表示取区域,$1,$2

 NF,$NF 2、NF 表示记录中的区域数量,$NF 取最后一个区域 3、FS(-F)指定分隔符 [root@oldboy tmp]# awk -F ":" "$5~/^(s|u)/{print $0}" passwdtest.txt

 sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin $5~表示对第 5 个字段进行正则匹配,!~表示不匹配 上例是说选取每一行中第五个字段是以 s 或 u 开头的匹配行,打印出整行 [root@oldboy tmp]# ifconfig eth0|awk -F "addr:| Bcast" "NR==2{print $2}"

 192.168.0.103 取 IP 直接选择 IP 前后字符作为分隔符 [root@oldboy tmp]# ifconfig eth0|awk -F "r:| B" "NR==2{print $2}"

 192.168.0.103

 [root@oldboy tmp]# awk -F ":" --posix "$1~/o{2}/{print NR,$1,$NF}" passwdtest.txt

 1 root /bin/bash

 [root@oldboy tmp]# awk -F ":" --posix "$1!~/o{1,2}/{print NR,$1,$NF}" passwdtest.txt

  2 bin /sbin/nologin 4 adm /sbin/nologin 5 lp /sbin/nologin 6 sync /bin/sync 8 halt /sbin/halt 9 mail /sbin/nologin 10 uucp /sbin/nologin --posix 表示使用了元字符,匹配时使用了{},!~表示取反

 [root@oldboy tmp]# awk "NR==1||NR==4{print NR,$0}" passwdtest.txt

 1 root:x:0:0:root:/root:/bin/bash 4 adm:x:3:4:adm:/var/adm:/sbin/nologin ||表示第一行和第 4 行

 [root@oldboy tmp]# awk "NR==1,NR==4{print NR,$0}" passwdtest.txt

  用逗号分开表示第一行到第 4 行 [root@oldboy tmp]# awk -F ":" "$1~/^root/,$1~/^adm/{print NR,$0}" passwdtest.txt

 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin

 这也是一个表范围的例子,第一个字段以 root 开头到 adm 开头的这个范围 [root@oldboy tmp]# awk -F ":" "$1~/^root/,NR==3{print NR,$0}" passwdtest.txt

  1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 两种表范围的方式也可以混合使用

 抓取服务的端口号:

 awk -F "[ /]+" "$1~/^(ftp|http|https|mysql|ssh)$/{print $1,$2}" /etc/services |uniq(重要)

  BEGIN 模块:

 awk 需要先执行完 BEGIN 模式,才对输入文件做处理,常用来修改内置变量,ORS,RS,FS,OFS 的值 可以不输入文件就测试 BEGIN:例:

 [root@oldboy ~]# awk "BEGIN{print "hello world"}"

  hello world

 [root@oldboy tmp]# awk "BEGIN{FS=":";OFS="***"}""{print $1,$3}" passwdtest.txt

 root***0 bin***1 daemon***2 adm***3 lp***4 sync***5 shutdown***6 halt***7 mail***8 uucp***10 通过 BEGIN 模式来更改 FS 和 OFS 的值;BEGIN 模式的操作如果有两个以上的语句,需要用冒号分隔。FS 与 OFS 实际就是一个替换的过程。

 END 模块 END 模块在 awk 读取完所有文件的时候,在执行 END 模块,一般用来输出一个结果(累加,数组结果)

 与 BEGIN 模式相对应的 END 模式,格式一样,但是 END 模式仅在 AWK 处理完所有输入行后才进行处理,并且 END 模式下 AWK 不匹配任何输入行。

 [root@oldboy tmp]# awk "/^$/{a=a+1;print a}" /etc/services

 1 2 3 4 5 6 7

 8 9 10 11 12 13 14 15 16 [root@oldboy tmp]# awk "/^$/{a=a+1}""END{print a}" /etc/services

 16(不显示过程,只显示结果)

 例:统计 passwd 文件中第 3 个字段大于等于 3 的行数 [root@oldboy tmp]# awk -F ":" "$3>=3{a=a+1;print a}" passwdtest.txt

  1 2 3 4 5 6 7 [root@oldboy tmp]# awk -F ":" "$3>=3{a=a+1}END{print a}" passwdtest.txt

 7

 [root@oldboy tmp]# awk -F ":" "$3>=3{a++}END{print a}" passwdtest.txt

 7(a++等价 a=a+1)

 几种运算表达式:

 a=a+1 ==> a++ a=a+2==>a+=2 a=a+$0==>a+=$0

 面试题:1+…+100

  1 加到 100 的值,用 awk 实现

 案例题:找出环境变量$PATH 中,所有只有三个任意字符的命令,例如 tee,并将它们重定向到 command.txt 中,要求一行显示一个,并在文件尾部统计它们的个数。

 [root@oldboy ~]# find $(echo $PATH|tr ":" " ") -type f -name "???" |awk "{a++}END{print "result:" a}"

  find: `/root/bin": No such file or directory result:99

 awk 数组结构:

 数组名 元素名

 元素的值 arrayname[string]=value awk 数组-取每个元素的值 for(key in array)

 awk 数组小结:

 1、 awk 数组去重; 2、 选好分隔符-F “/” 3、 选好处理的区域,print $1,$2,$3 4、 array[$3]++ 5、 先处理,最后 END 模块输出 6、 输出 awk 数组我们使用 for(key in array)

 7、 for()循环 8、 key in array 手去框里抓苹果 9、 key 就是苹果的名字(数组元素的名字)

 10、 array 数组名(框的名字)

 11、 打印输出 print

 key,array[key]

  案例题:处理以下文件内容,将域名取出来并根据域名进行计数排序处理:

 http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html

 方法 1、 [root@oldboy tmp]# awk -F "/" "{print $3}" awkfile |sort|uniq -c

  1 mp3.etiantian.org

  2 post.etiantian.org

  3 www.etiantian.org [root@oldboy tmp]# awk -F "/" "{print $3}" awkfile |uniq -c (如果不 sort 排序,uniq 只会处理相同行,所以和 sort 连用比较好)

  2 www.etiantian.org

  1 post.etiantian.org

  1 mp3.etiantian.org

  1 www.etiantian.org

  1 post.etiantian.org

 方法 2、用 awk 数组的方法

 [root@oldboy tmp]# awk -F "/" "$3~/www.etiantian.org/{array["www.etiantian.org"]++;print

 array["www.etiantian.org"]}" awkfile 1 2 3 [root@oldboy tmp]# awk -F "/" "{array[$3]++;print $3,array[$3]}" awkfile www.etiantian.org 1 www.etiantian.org 2 post.etiantian.org 1 mp3.etiantian.org 1 www.etiantian.org 3 post.etiantian.org 2 [root@oldboy tmp]# awk -F "/" "{array[$3]++}END{print "www.etiantian.org",array["www.etiantian.org"]}" awkfile

  www.etiantian.org 3

 [root@oldboy tmp]# awk -F "/" "{array[$3]++}END{for(key in array)print key,array[key]}" awkfile

 mp3.etiantian.org 1 post.etiantian.org 2 www.etiantian.org 3

相关热词搜索: 命令 学习 awk