• 工作总结
  • 工作计划
  • 心得体会
  • 领导讲话
  • 发言稿
  • 演讲稿
  • 述职报告
  • 入党申请
  • 党建材料
  • 党课下载
  • 脱贫攻坚
  • 对照材料
  • 主题教育
  • 事迹材料
  • 谈话记录
  • 扫黑除恶
  • 实施方案
  • 自查整改
  • 调查报告
  • 公文范文
  • 思想汇报
  • 当前位置: 雅意学习网 > 文档大全 > 思想汇报 > 正文

    awk命令学习

    时间:2021-05-01 13:55:58 来源:雅意学习网 本文已影响 雅意学习网手机站

     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

    • 文档大全
    • 故事大全
    • 优美句子
    • 范文
    • 美文
    • 散文
    • 小说文章