• linux基础学习-18.4-awk记录和字段


    接下来我给大家带来两个新概念记录和字段,这里为了方便大家理解可以把记录就当作行即记录==行,字段相当于列,字段==列。

    1、记录(行)

    查看一下下面这段文字

    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    
    思考:

    一共有多少行呢?你如何知道的?通过什么标志?

    awk对每个要处理的输入数据认为都是具有格式和结构的,而不仅仅是一堆字符串。默认情况下,每一行内容都是一条记录,并以换行符分隔( )结束

    2、记录分隔符-RS

    • awk默认情况下每一行都是一个记录(record)

    • RS既record separator输入输出数据记录分隔符,每一行是怎么没的,表示每个记录输入的时候的分隔符,既行与行之间如何分隔。

    • NR既number of record 记录(行)号,表示当前正在处理的记录(行)的号码。

    • ORS既output record separator 输出记录分隔符。

    awk使用内置变量RS来存放输入记录分隔符,RS表示的是输入的记录分隔符,这个值可以通过BEGIN模块重新定义修改

    1)使用“/”为默认记录分隔符

    示例文件:

    [root@oldboy ~]# cat /server/files/awkfile.txt 
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    
    [root@oldboy ~]# awk 'BEGIN{RS="/"}{print NR,$0}' /server/files/awkfile.txt 
    1 root:x:0:0:root:
    2 root:
    3 bin
    4 bash
    bin:x:1:1:bin:
    5 bin:
    6 sbin
    7 nologin
    daemon:x:2:2:daemon:
    8 sbin:
    9 sbin
    10 nologin
    adm:x:3:4:adm:
    11 var
    12 adm:
    13 sbin
    14 nologin
    lp:x:4:7:lp:
    15 var
    16 spool
    17 lpd:
    18 sbin
    19 nologin
    sync:x:5:0:sync:
    20 sbin:
    21 bin
    22 sync
    shutdown:x:6:0:shutdown:
    23 sbin:
    24 sbin
    25 shutdown
    halt:x:7:0:halt:
    26 sbin:
    27 sbin
    28 halt
    mail:x:8:12:mail:
    29 var
    30 spool
    31 mail:
    32 sbin
    33 nologin
    uucp:x:10:14:uucp:
    34 var
    35 spool
    36 uucp:
    37 sbin
    38 nologin
    

    命令说明:

    在每行的开始先打印输出NR(记录号行号),并打印出每一行$0(整行)的内容。

    我们设置RS(记录分隔符)的值为“/”,表示一行(记录)以“/”结束

    在awk眼中,文件是从头到尾一段连续的字符串,恰巧中间有些 (回车换行符), 也是字符哦。

    我们回顾下“行(记录)”到底是什么意思?
    • 行(记录):默认以 (回车换行)结束。而这个行的结束不就是记录分隔符嘛。
    • 所以在awk中,RS(记录分隔符)变量表示着行的结束符号(默认是回车换行)
    在工作中,我们可以通过修改RS变量的值来决定行的结束标志,最终来决定“每行”的内容。
    为了方便人们理解,awk默认就把RS的值设置为“ ”

    注意:

    awk的BEGIN模块,我会在后面(模式-BEGIN模块)详细讲解,此处大家仅需要知道在BEGIN模块里面我们来定义一些awk内置变量即可。

    3、对$0的认识

    • 如2、的例子,可以看出awk中$0表示整行,其实awk使用$0来表示整条记录。记录分隔符存在RS变量中,或者说每个记录以RS内置变量结束。

    • 另外,awk对每一行的记录号都有一个内置变量NR来保存,每处理完一条记录,NR的值就会自动+1

    • 下面通过示例来加深印象。

    1)NR记录号

    [root@oldboy ~]# awk '{print NR,$0}' /server/files/awkfile.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
    5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    6 sync:x:5:0:sync:/sbin:/bin/sync
    7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    8 halt:x:7:0:halt:/sbin:/sbin/halt
    9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    

    命令说明:

    NR既number of record,当前记录的记录号,刚开始学也可以理解为行号。

    $0表示整行或者说整个记录

    4、企业面试题:按单词出现频率降序排序(计算文件中每个单词的重复数量)

    注:(此处使用sort与uniq即可)

    题目

    题目创建方法:sed -r '1,10s#[^a-zA-Z]+# #g' /etc/passwd>/server/files/count.txt
    
    [root@oldboy files]# cat /server/files/count.txt 
    root x root root bin bash
    bin x bin bin sbin nologin
    daemon x daemon sbin sbin nologin
    adm x adm var adm sbin nologin
    lp x lp var spool lpd sbin nologin
    sync x sync sbin bin sync
    shutdown x shutdown sbin sbin shutdown
    halt x halt sbin sbin halt
    mail x mail var spool mail sbin nologin
    uucp x uucp var spool uucp sbin nologin
    

    思路:

    让所有单词排成一列,这样每个单词都是单独的一行

    1)设置RS值为空格

    2)将文件里面的所有空格替换为回车换行符“ ”

    3)grep所有连续的字母,grep -o参数让他们排成一列

    方法一:

    [root@oldboy files]# awk 'BEGIN{RS="[ ]+"}{print $0}' count.txt | sort |uniq -c|sort
          1 
          1 bash
          1 lpd
          2 daemon
          2 lp
          3 adm
          3 halt
          3 mail
          3 root
          3 shutdown
          3 spool
          3 sync
          3 uucp
          4 var
          5 bin
          6 nologin
         10 x
         12 sbin
    

    方法二:

    [root@oldboy files]# cat count.txt | tr " " "
    " | sort | uniq -c | sort
          1 bash
          1 lpd
          2 daemon
          2 lp
          3 adm
          3 halt
          3 mail
          3 root
          3 shutdown
          3 spool
          3 sync
          3 uucp
          4 var
          5 bin
          6 nologin
         10 x
         12 sbin
    

    方法三:

    [root@oldboy files]# grep -o "[a-zA-Z]+" count.txt | sort | uniq -c | sort
          1 bash
          1 lpd
          2 daemon
          2 lp
          3 adm
          3 halt
          3 mail
          3 root
          3 shutdown
          3 spool
          3 sync
          3 uucp
          4 var
          5 bin
          6 nologin
         10 x
         12 sbin
    

    5、awk记录知识小结

    NR存放着每个记录的号(行号)读取新行时候会自动+1

    RS是输入数据的记录的分隔符,简单理解就是可以指定每个记录的结尾标志。

    RS作用就是表示一个记录的结束

    当我们修改了RS的值,最好配合NR(行)来查看变化,也就是修改了RS的值通过NR查看结果,调试awk程序。

    ORS输出数据的记录的分隔符

    awk学习技巧一则:

    大象放冰箱分几步?打开冰箱,把大象放进去,关闭冰箱门。

    awk也是一样的,一步一步来,先修改了RS,然后用NR调试,看看到底如何分隔的。然后通过sort排序,uniq -c去重

    6 、字段(列) {#字段列}

    • 每条记录都是由多个区域(field)组成的,默认情况下区域之间的分隔符是由空格(即空格或制表符)来分隔,并且将分隔符记录在内置变量FS中,每行记录的区域数保存在awk的内置变量NF中。

    • FS既field separator,输入字段(列)分隔符。分隔符就是菜刀,把一行字符串切为很多个区域。

    • NF既number of fileds,表示一行中列(字段)的个数,可以理解为菜刀切过一行后,切成了多少份。

    OFS输出字段(列)分隔符

    • awk使用内置变量FS来记录区域分隔符的内容,FS可以在命令行上通过-F参数来更改,也可以通过BEGIN模块来更改。

    • 然后通过$n,n是整数,来取被切割后的区域,$1取第一个区域,$2取第二个区域,$NF取最后一个区域。

    下面我们通过示例来加强学习。

    1)指定分隔符

    [root@oldboy files]# awk -F ":" 'NR>=2&&NR<=5{print $1,$3}' /server/files/awkfile.txt 
    bin 1
    daemon 2
    adm 3
    lp 4
    

    命令说明:

    以:(冒号)为分隔符,显示第2行到第5行之间的第一区域和第三区域。

    • 此处的FS知识一个字符,其实它可以指定多个的,此时FS指定的值可以是一个正则表达式。

    • 正常情况下,当你指定分隔符(非空格)的时候,例如指定多个区域分隔符,每个分隔符就是一把刀,把左右两边切为两个部分。

    **企业面试题:**同时取出chensiqi和215379068这两个内容(指定多分隔符)

    [root@oldboy files]# echo "I am chensiqi,my qq is 1234567890">>/server/files/chensiqi.txt
    [root@oldboy files]# cat /server/files/chensiqi.txt 
    I am chensiqi,my qq is 1234567890
    

    思路:

    我们用默认的想法一次使用一把刀,需要配合管道的。如何同时使用两把刀呢?看下面的结果

    [root@oldboy files]# awk -F "[ ,]" '{print $3,$NF}' /server/files/chensiqi.txt 
    chensiqi 1234567890
    

    命令说明:

    通过命令-F参数指定区域分隔符

    [ ,]是正则表达式里面的内容,它表示一个整体,“一个”字符,既空格或者逗号(,),合并在一起,-F “[ ,]”就表示以空格或者逗号(,)为区域分隔符

    小技巧:

    在动作(‘{print $3,$NF}’)里面的逗号,表示空格,其实动作中的逗号就是OFS的值,我们会在后面说明。刚开始大家把动作中的都逗号,当作空格即可。

    2)默认分隔符和指定分隔符会有些差异

    [root@oldboy files]# ifconfig eth0 | awk 'NR==2' >/server/files/awkblank.txt
    [root@oldboy files]# cat /server/files/awkblank.txt 
              inet addr:192.168.197.133  Bcast:192.168.197.255  Mask:255.255.255.0
    

    #默认分隔符时候

    [root@oldboy files]# awk '{print $1}' /server/files/awkblank.txt 
    inet
    

    #指定分隔符时候

    [root@oldboy files]# awk -F "[ :]+" '{print $1}' /server/files/awkblank.txt 
    [root@oldboy files]# awk -F "[ :]+" '{print $2}' /server/files/awkblank.txt 
    inet
    

    命令说明:

    awk默认的FS分隔符对于空格序列,一个空格或多个空格tab都认为是一样的,一个整体。

    这个文件的开头有很多连续的空格,然后才是inet这个字符

    当我们使用默认的分隔符的时候,$1是有内容的。

    当我们指定其他分隔符(非空格)时候,区域会有所变化

    到底为何会这样,我们在这里不再深入研究,只要了解有这种情况,注意一下即可。

    7、ORS与OFS简介

    现在说说ORS和OFS这两个内置变量的含义。

    • RS是输入记录分隔符,决定awk如何读取或分隔每行(记录)
    • ORS表示输出记录分隔符,决定awk如何输出一行(记录)的,默认是回车换行( )
    • FS是输入区域分隔符,决定awk读入一行后如何再分为多个区域。
    • OFS表示输出区域分隔符,决定awk输出每个区域的时候使用什么分隔她们。
    • awk无比强大,你可以通过RS,FS决定awk如何读取数据。你也可以通过修改ORS,OFS的值指定awk如何输出数据。

    8、字段与记录小结

    现在你应该会对awk的记录字段有所了解了,下面我们总结一下,学会给阶段性知识总结是学好运维的必备技能。

    • RS记录分隔符,表示每行的结束标志
    • NR行号(记录号)
    • FS字段分隔符,每列的分隔标志或结束标志
    • NF就是每行有多少列,每个记录中字段的数量
    • $符号表示取某个列(字段),$1$2$NF
    • NF表示记录中的区域(列)数量,$NF取最后一个列(区域。)
    • FS(-F)字段(列)分隔符,-F(FS)“:”<==>‘BEGIN{FS=':'}’
    • RS 记录分隔符(行的结束标识)
    • NR 行号
    • 选好合适的刀FS(***),RS,OFS,ORS
    • 分隔符==>结束标识
    • 记录与区域,你就对我们所谓的行与列,有了新的认识(RS,FS)

    9、awk基础入门总结

    到了这里我们回头看看,我们之前学习的内容。

    • awk的命令行结构
    • awk的模式和动作
    • awk的记录和字段

    比较核心常用的是字段。

    另外这些企业面试题可是学会awk的必备,必须自己也能写出来。

    练习题:

    1、按单词出现频率降序排序(计算文件中每个单词的重复数量)

    2、同时取出chensiqi和215379068这两个内容(指定多分隔符)

    3、说说ORS和OFS这两个内置变量的含义

  • 相关阅读:
    MEF程序设计指南一:在应用程序中宿主MEF
    Silverlight & Blend动画设计系列十三:三角函数(Trigonometry)动画之飘落的雪花(Falling Snow)
    【Silverlight】Bing Maps开发应用与技巧六:使用样式美化图钉(Pushpin)控件的ToolTip外观
    线程的两种类型
    几种VC++数据库开发技术的比较
    Never use AfxEndThread! 一个非常好的例子
    我的 Visual C++ 6.0学习网站
    DB2 基础: 日期和时间的使用
    Boost::Regex 使用方法 (英文)
    vc访问数据库 (并弹出数据源浏览窗口与用户交互)
  • 原文地址:https://www.cnblogs.com/Klanti/p/9143654.html
Copyright © 2020-2023  润新知