zoukankan      html  css  js  c++  java
  • 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这两个内置变量的含义

  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/Klanti/p/9143654.html
Copyright © 2011-2022 走看看