关于awk

作者: RedHatMe | 来源:发表于2018-08-06 15:28 被阅读0次

    1 awk标准

    awk {pattern + action } file
    action 可以有多条语句 用分号隔开,如 :

    【大括号里面用分号】
    
    awk 'BEGIN {count=0;print "[start] user count is ",count} 
    {count=count+1;print $0} 
    END{print "[end] user count is ",count}' /etc/passwd
    

    2 基础

    以下方便 理解记忆

    image.png

    R:record 记录
    F:field 字段
    NR: 有多少条记录
    NF: 一行有多少个字段
    FS:fileld Separator 字段分隔符

    [awk FS分隔符默认的只是带1个或者多个空格]
    如果需要一个或者多个tab 则 :awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' file.txt
    

    RS:record Separator 记录与记录(行与行的)分隔符 一般是换行符
    OFS:输出 域分隔符
    一般 用BEGIN 指定输出分隔符,格式化文件

    如:awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txt
    

    ORS:输出 行分隔符

    关于BEGIN END:

    在许多编程情况中,可能需要在 awk开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。
    如果是处理完整个文件执行的语句 就END。

    3 正则:

    关于正则的 正式理论:

    正则表达式的基本元素包括普通字符和元字符:普通字符,没有隐含意义,字面理解;元字符,shell赋予了他们超越字面的意义。下面是基本正则表达式中元字符集合及其意义(POSIX标准将正则表达式分做基本正则表达式和扩展正则表达式,大部分应用使用基本正则表达式)。

    基本正则表达式

    image.png

    扩展正则表达式

    image.png

    实用:

    http://tool.oschina.net/regex/ 匹配在线测试
    awk '/sun/' file 或者 awk -F: '5~/root/{print0}' file 这种带// 的是可以直接匹配相关字符的
    一些常见的匹配:
    ^ 表示在文件中的行首进行匹配。 例如:/^sun/表示模式匹配以sun开头的行。
    表示在文件中的行尾进行匹配。 例如:/sun/表示模式匹配以sun结尾的行。
    . 表示与任何单个字符串匹配。 注意:是单个字符串。
    [ABC] 表示与[]内的任意一字符匹配。 例如:/[Mm]oon/表示模式匹配包含Moon或moon的行。
    [A-Ca-c] 表示与A-C及a-c范围内的单个字符匹配。 例如:/^[a-b][c-d][e-f]/表示开始第一个字符是a或b,第二个字符是c或d,第三个字符是e或f。同样的道理,/[a-b][c-d][e-f]$/表示从记录的后面开始匹配。
    Desk|Chair 表示与Desk和Chair中的任意一个匹配。
    [^ABC] 与除[ ]内的所有字符以外的任一字符匹配。【这时候方括号里面的^是取反的意思】
    [ABC]* 表示与A、B、C中任意一个出现0次或多次的字符相匹配。
    [ABC]+ 表示与A、B、C中任意一个出现1次或多次的字符相匹配。
    <the> 精确匹配the这个单词,一点都不能差。
    JP{3}L 匹配值为JPPPL
    JP{3,}L P至少出现3次
    [a-z]{5} 精确匹配5个小写字母,如hello,house
    re(a|e|o)d匹配readreed reod
    RE1|RE2|RE3 表示多个正则表达式的或关系

    4 其他

    网上的一个问题:

    echo "a[b]c"|awk -F'[][]' '{ print 12 3 }' 得到abc echo "ac"|awk -F'[\\[\\]]' '{ print1 23 }' 得到abc
    echo "a[b]c" |awk -F "[][]" '{print 12 3}' 得到abc awk 'BEGIN{FS="\\[|\\]"}{print1,2,3}'
    echo "a[b]c" |awk -F "[[]]" '{print 12 3 }'1 为a[b]c 23 为空
    echo "a[b]c"|awk -F'[[]]' '{ print 12 3 }'1 为a[b]c 23 为空
    [][]处理成为匹配]或[
    [[]]处理成为匹配[]
    原因可能是字符组不允许为空:
    [][]中第一个]真正作为]字符,而不是元字符,接着是字符[再遇到元字符]后字符组构造完毕,匹配]或[
    [[]]同理第二个[也没有作为元字符

    关于sub 和 gsub :

    其实就是替换字符串
    sub 函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。格式如下:

            sub (regular expression, substitution string):
            sub (regular expression, substitution string, target string)
    

    实例:

            $ awk '{ sub(/test/, "mytest"); print }' testfile
            $ awk '{ sub(/test/, "mytest"); $1}; print }' testfile
    

    第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub

    第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。

    gsub 函数作用如sub,但它在整个文档中进行匹配。格式如下:

            gsub (regular expression, substitution string)
            gsub (regular expression, substitution string, target string)
    

    实例:

            $ awk '{ gsub(/test/, "mytest"); print }' testfile
            $ awk '{ gsub(/test/, "mytest" , $1) }; print }' testfile
    

    第一个例子在整个文档中匹配test,匹配的都被替换成mytest。

    第二个例子在整个文档的第一个域中匹配,所有匹配的都被替换成mytest。

    awk 代码块:

    【if for while】

    ! /matchxxx/ {print 12}
    等价 if (0 !~/matchxxx/ ){ print1 $2}

    for: s是默认数组 任何字符都可用做数组
    统计网络状态
    netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print a,s[a]}'

    相关文章

      网友评论

          本文标题:关于awk

          本文链接:https://www.haomeiwen.com/subject/yrnwvftx.html