zoukankan      html  css  js  c++  java
  • 文本三剑客

    grep

    文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

    grep [OPTIONS] PATTERN [FILE…]

    • –color=auto: 对匹配到的文本着色显示 
    • -v: 显示不被pattern匹配到的行
    • -i: 忽略字符大小写
    • -n: 显示匹配的行号
    • -c: 统计匹配的行数
    • -o: 仅显示匹配到的字符串
    • -q: 静默模式,不输出任何信息 
    • -A #: after, 显示匹配到的行和后#行
    • -B #: before, 显示匹配到的行和前#行
    • -C #:context, 显示匹配到的行和前后各#行
    • -e: 实现多个选项间的逻辑or关系。grep –e ‘cat ’ -e ‘dog’ file 
    • -w: 整行匹配整个单词
    • -E: 使用扩展正则表达式
    • -F: 相当于fgrep,不支持正则表达式

    sed

    sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”( pattern space),接着用sed命令处理缓冲区中的内容 ,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变 ,除非你使用重定向存储输出。Sed主要用来自动编辑一 个或多个文件,简化对文件的反复操作,编写转换程序等

    sed [option]… script inputfile…

    • -n: 不输出模式空间内容到屏幕,即不自动打印
    • -e: 多点编辑
    • -f: /PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本 
    • -r: 支持使用扩展正则表达式
    • -i: 原处编辑
    • -i.bak: 原处编辑,编辑前复制源文件为源文件名称+.bak后缀

    script=地址定界+编辑命令

    地址定界
    • 不给地址:对全文进行处理 
    • 单地址:
      • #: 指定的行
      • /pattern/:被此处模式所能够匹配到的每一行 
    • 地址范围:
      • #,#: 
      • #,+# 
      • /pat1/,/pat2/ 
      • #,/pat1/
    • ~:步进
      • 1~2: 从1开始,步进2,表示奇数行
      • 2~2 从2开始,步进2,表示偶数行

    编辑命令

    • d: 删除模式空间匹配的行
    • p: 显示模式空间中的内容
    • a []text: 在指定行后面追加文本支持使用 实现多行追加
    • i []text: 在行前面插入文本
    • c []text: 替换行为单行或多行文本
    • w /path/somefile: 保存模式匹配的行至指定文件
    • r /path/somefile: 读取指定文件的文本至模式空间中
    • 匹配到的行后 =: 为模式空间中的行打印行号
    • !: 模式空间中匹配行取反处理

    查找替换

    • s///:查找替换,支持使用其它分隔符,s@@@,s### 
    • 替换标记:
      • g: 行内全局替换
      • p: 显示替换成功的行
      • w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中

    高级编辑命令

    • h: 把模式空间中的内容覆盖至保持空间中
    • H:把模式空间中的内容追加至保持空间中
    • g: 从保持空间取出数据覆盖至模式空间 
    • G:从保持空间取出内容追加至模式空间
    • x: 把模式空间中的内容与保持空间中的内容进行互换 
    • n: 读取下一行到模式空间,且后期的操作命令只对该行有效 
    • N: 读取下一行到模式空间,且后期的操作命令对模式空间的所有行有效 
    • d: 删除模式空间中的行
    • D:删除当前模式空间开端至 的内容(不再传至标准输 出),放弃之后的命令,但是对剩余模式空间重新执行sed

    awk

    AWK是由Aho, Weinberger, Kernighan这三个人共同开发出的一优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。

    awk [options] ‘program’ var=value file…
    awk [options] -f programfile var=value file…
    awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }’ file …

    • options
      • -F 指明输入时用到的字段分隔符
      • -v var=value: 自定义变量
      • -f 指定awk程序文件
    • BEGIN{ action;… }: 读入文本之前执行{action;…}
    • END{ action;… }: 文本处理完之后执行{ action;… }
    • pattern{ action;… }: pattern的返回值为True时,才执行{action;…},pattern可以有以下几种:
      • 如果未指定pattern: 匹配每一行
      • /regular expression/: 仅处理能够被模式(正则表达式匹配到的行,需要用/ /括起来
      • relational expression: 关系表达式,
        */pat1/,/pat2/: 行范围startline,endline不支持直接给出数字格式
      • True: 结果为非0值,非空字符串
      • False: 结果为空字符串或0值

    awk工作流程

    • 第一步:执行BEGIN{action;… }语句块中的语句
    • 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这 个过程,直到文件全部被读取完毕。
    • 第三步:当读至输入流末尾时,执行END{action;…}语句块。
      .
    • BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常 可以写在BEGIN语句块中
    • END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它 也是一个可选语句块
    • pattern语句块中的通用命令是最重要的部分,也是可选的。如果 没有提供pattern语句块,则默认执行{ print },即打印每一个读取 到的行,awk读取的每一行都会执行该语句块

    awk内置命令

    print

    print item1, item2, …

    特性

    • item之间用逗号分隔符
    • 输出的各item可以是字符串、数值、当前记录的字段、变量、awk表达式
    • 省略item,相当于print$0
    printf

    printf “FORMAT”, item1, item2, …

    特性

    • 必须指定FORMAT
    • 不会自动换行,需要显式给出换行控制符,
    • FORMAT中需要分别为后面每个item指定格式符 

    FORMAT=格式符+修饰符

    • 格式符
      • %c: 显示字符的ASCII码 
      • %d, %i: 显示十进制整数 
      • %e, %E:显示科学计数法数值
      • %f: 显示为浮点数
      • %g, %G:以科学计数法或浮点形式显示数值 
      • %s: 显示字符串
      • %u: 无符号整数
      • %%: 显示%自身
    • 修饰符:
      • #[.#]: 第一个数字控制显示的宽度,第二个#表示小数点后精度
      • -: 左对齐(默认右对齐) %-15s
      • +: 显示数值的正负符号 %+d

    awk变量

    内置变量
    • FS: 输入字段分隔符,默认为空白字符
    • OFS: 输出字段分隔符,默认为空白字符
    • RS: 输入记录分隔符,指定输入时的换行符,原换行符仍有效
    • ORS: 输出记录分隔符,输出时用指定符号代替换行符
    • NF: 当前行的字段数量
    • NR: 当前行的行号
    • FNR: 各文件分别计数,行号
    • FILENAME: 当前文件名
    • ARGC: 命令行参数的个数
    • ARGV: 数组,保存的是命令行所给定的各参数 
    自定义变量(区分字符大小写)
    • -v var=value
    • 在program中直接定义

    awk操作符

    • 算术操作符: x+y, x-y, x*y, x/y, x^y, x%y
    • -x: 转换为负数
    • +x: 转换为数值
    • 字符串操作符: 没有符号的操作符,字符串连接 
    • 赋值操作符: =, +=, -=, *=, /=, %=, ^=,++, —
    • 比较操作符: ==, !=, >, >=, <, <=
    • 模式匹配符: 支持正则表达式
      • ~: 左边是否和右边匹配包含
      • !~: 是否不匹配
    • 逻辑操作符:与&&,或||,非!
    • 条件表达式(三目表达式): selector?if-true-expression:if-false-expression

    awk action

    • Expressions: 算术、比较表达式等 
    • Control statements: if、 while等 
    • Compound statements: 组合语句 
    • input statements: 没用过
    • output statements: print、printf等

    awk 控制语句

    分支语句
    • if(condition){statement;…}[else statement]
    • if(condition1){statement1}else if(condition2){statement2}else{statement3}
    • switch(expression){case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2; …; default: statementN}
    循环语句
    • while(condition){statement;…}
    • do{statement;…}while(condition)
    • for(expr1;expr2;expr3) {statement;…}
    控制语句
    • next: 提前结束对本行处理而直接进入下一行处理
    • break [n] 
    • continue [n]

    awk 数组

    数组格式

    array[index]

    • index
      • 可使用任意字符串;字符串要使用双引号括起来
      • 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
    数组遍历

    for(idx in array){for-body}

    awk函数

    内置函数
    • rand(): 返回0和1之间一个随机数,使用之前需要先调用srand()函数
    • length([s]): 返回指定字符串的长度
    • sub(r,s,[t]): 对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s

    • gsub(r,s,[t]): 对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
    • split(s,array,[r]): 以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…
    自定义函数

    语法

    示例

    awk中调用shell命令

    空格是awk中的字符串连接符,如果system中需要使用awk中 的变量可以使用空格分隔,或者说除了awk的变量外其他一律 用””引用起来。

    示例:

    awk 脚本

    普通awk脚本

    示例

    带变量的awk脚本

    这种方式传递给awk脚本的变量在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数

    awk

    awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
    awk处理过程: 依次对每一行进行处理,然后输出
    awk命令形式:
    awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
     [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
    '  '          引用代码块
    BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
    //           匹配代码块,可以是字符串或正则表达式
    {}           命令代码块,包含一条或多条命令
    ;          多条命令使用分号分隔
    END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
     
    特殊要点:
    $0           表示整个当前行
    $1           每行第一个字段
    NF          字段数量变量
    NR          每行的记录号,多文件记录递增
    FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始
               制表符
              换行符
    FS          BEGIN时定义分隔符
    RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
    ~            匹配,与==相比不是精确比较
    !~           不匹配,不精确比较
    ==         等于,必须全部相等,精确比较
    !=           不等于,精确比较
    &&      逻辑与
    ||             逻辑或
    +            匹配时表示1个或1个以上
    /[0-9][0-9]+/   两个或两个以上数字
    /[0-9][0-9]*/    一个或一个以上数字
    FILENAME 文件名
    OFS       输出字段分隔符, 默认也是空格,可以改为制表符等
    ORS         输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
    -F'[:#/]'   定义三个分隔符
     
    print & $0
    print 是awk打印指定内容的主要命令
    awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd  
    awk '{print " "}' /etc/passwd                                           //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本
    awk '{print "a"}'   /etc/passwd                                        //输出相同个数的a行,一行只有一个a字母
    awk -F":" '{print $1}'  /etc/passwd 
    awk -F: '{print $1; print $2}'   /etc/passwd                   //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
    awk  -F: '{print $1,$3,$6}' OFS=" " /etc/passwd        //输出字段1,3,6,以制表符作为分隔符
     
    -f指定脚本文件
    awk -f script.awk  file
    BEGIN{
    FS=":"
    }
    {print $1}               //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定
     
    awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test 
    I find 4 blank lines.
     ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'                    //计算文件大小
    total size is 17487
     
    -F指定分隔符
    $1 指指定分隔符后,第一个字段,$3第三个字段, 是制表符
    一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格
    awk -F":" '{print $1}'  /etc/passwd
    awk -F":" '{print $1 $3}'  /etc/passwd                       //$1与$3相连输出,不分隔
    awk -F":" '{print $1,$3}'  /etc/passwd                       //多了一个逗号,$1与$3使用空格分隔
    awk -F":" '{print $1 " " $3}'  /etc/passwd                  //$1与$3之间手动添加空格分隔
    awk -F":" '{print "Username:" $1 " Uid:" $3 }' /etc/passwd       //自定义输出  
    awk -F: '{print NF}' /etc/passwd                                //显示每行有多少字段
    awk -F: '{print $NF}' /etc/passwd                              //将每行第NF个字段的值打印出来
     awk -F: 'NF==4 {print }' /etc/passwd                       //显示只有4个字段的行
    awk -F: 'NF>2{print $0}' /etc/passwd                       //显示每行字段数量大于2的行
    awk '{print NR,$0}' /etc/passwd                                 //输出每行的行号
    awk -F: '{print NR,NF,$NF," ",$0}' /etc/passwd      //依次打印行号,字段数,最后字段值,制表符,每行内容
    awk -F: 'NR==5{print}'  /etc/passwd                         //显示第5行
    awk -F: 'NR==5 || NR==6{print}'  /etc/passwd       //显示第5行和第6行
    route -n|awk 'NR!=1{print}'                                       //不显示第一行
     
    //匹配代码块
    //纯字符匹配   !//纯字符不匹配   ~//字段值匹配    !~//字段值不匹配   ~/a1|a2/字段值匹配a1或a2   
    awk '/mysql/' /etc/passwd
    awk '/mysql/{print }' /etc/passwd
    awk '/mysql/{print $0}' /etc/passwd                   //三条指令结果一样
    awk '!/mysql/{print $0}' /etc/passwd                  //输出不匹配mysql的行
    awk '/mysql|mail/{print}' /etc/passwd
    awk '!/mysql|mail/{print}' /etc/passwd
    awk -F: '/mail/,/mysql/{print}' /etc/passwd         //区间匹配
    awk '/[2][7][7]*/{print $0}' /etc/passwd               //匹配包含27为数字开头的行,如27,277,2777...
    awk -F: '$1~/mail/{print $1}' /etc/passwd           //$1匹配指定内容才显示
    awk -F: '{if($1~/mail/) print $1}' /etc/passwd     //与上面相同
    awk -F: '$1!~/mail/{print $1}' /etc/passwd          //不匹配
    awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd        
     
    IF语句
    必须用在{}中,且比较内容用()扩起来
    awk -F: '{if($1~/mail/) print $1}' /etc/passwd                                       //简写
    awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd                                   //全写
    awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd            //if...else...
     
     
    条件表达式
    ==   !=   >   >=  
    awk -F":" '$1=="mysql"{print $3}' /etc/passwd  
    awk -F":" '{if($1=="mysql") print $3}' /etc/passwd          //与上面相同 
    awk -F":" '$1!="mysql"{print $3}' /etc/passwd                 //不等于
    awk -F":" '$3>1000{print $3}' /etc/passwd                      //大于
    awk -F":" '$3>=100{print $3}' /etc/passwd                     //大于等于
    awk -F":" '$3<1{print $3}' /etc/passwd                            //小于
    awk -F":" '$3<=1{print $3}' /etc/passwd                         //小于等于
     
    逻辑运算符
    && || 
    awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd         //逻辑与,$1匹配mail,并且$3>8
    awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
    awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd       //逻辑或
    awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd 
     
    数值运算
    awk -F: '$3 > 100' /etc/passwd    
    awk -F: '$3 > 100 || $3 < 5' /etc/passwd  
    awk -F: '$3+$4 > 200' /etc/passwd
    awk -F: '/mysql|mail/{print $3+10}' /etc/passwd                    //第三个字段加10打印 
    awk -F: '/mysql/{print $3-$4}' /etc/passwd                             //减法
    awk -F: '/mysql/{print $3*$4}' /etc/passwd                             //求乘积
    awk '/MemFree/{print $2/1024}' /proc/meminfo                  //除法
    awk '/MemFree/{print int($2/1024)}' /proc/meminfo           //取整
     
    输出分隔符OFS
    awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS=" " netstat.txt
    awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS=" " netstat.txt        
    //输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段
     
    输出处理结果到文件
    ①在命令代码块中直接输出    route -n|awk 'NR!=1{print > "./fs"}'   
    ②使用重定向进行输出           route -n|awk 'NR!=1{print}'  > ./fs
     
    格式化输出
    netstat -anp|awk '{printf "%-8s %-8s %-10s ",$1,$2,$3}' 
    printf表示格式输出
    %格式化输出分隔符
    -8长度为8个字符
    s表示字符串类型
    打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),
    第三个字段输出字符串类型(长度为10)
    netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s ",$1,$2,$3}'
    netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s ",NR,$1,$2,$3}'
     
    IF语句
    awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
    small
    small
    small
    large
    small
    small
    awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A," ",B}' /etc/passwd 
                                                                                                                      //ID大于100,A加1,否则B加1
    awk -F: '{if($3<100) next; else print}' /etc/passwd                         //小于100跳过,否则显示
    awk -F: 'BEGIN{i=1} {if(i<nf) print="" nr,nf,i++="" }'="" etc="" passwd=""   <="" span="">
    awk -F: 'BEGIN{i=1} {if(i<nf) {print="" nr,nf}="" i++="" }'="" etc="" passwd<="" span="">
    另一种形式
    awk -F: '{print ($3>100 ? "yes":"no")}'  /etc/passwd 
    awk -F: '{print ($3>100 ? $3": yes":$3": no")}'  /etc/passwd
     
    while语句
    awk -F: 'BEGIN{i=1} {while(i<nf) print="" nf,$i,i++}'="" etc="" passwd ="" <="" div="">
    7 root 1
    7 x 2
    7 0 3
    7 0 4
    7 root 5
    7 /root 6
     
    数组
    netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i," ",a[i]}'
    netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s ", i," ",a[i]}'
    9523                               1     
    9929                               1     
    LISTEN                            6     
    7903                               1     
    3038/cupsd                   1     
    7913                               1     
    10837                             1     
    9833                               1     
     
    应用1
    awk -F: '{print NF}' helloworld.sh                                                       //输出文件每行有多少字段
    awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh                                 //输出前5个字段
    awk -F: '{print $1,$2,$3,$4,$5}' OFS=' ' helloworld.sh                 //输出前5个字段并使用制表符分隔输出
    awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS=' ' helloworld.sh           //制表符分隔输出前5个字段,并打印行号
     
    应用2
    awk -F'[:#]' '{print NF}'  helloworld.sh                                                  //指定多个分隔符: #,输出每行多少字段
    awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS=' ' helloworld.sh   //制表符分隔输出多字段
     
    应用3
    awk -F'[:#/]' '{print NF}' helloworld.sh                                               //指定三个分隔符,并输出每行字段数
    awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh     //制表符分隔输出多字段
     
    应用4
    计算/home目录下,普通文件的大小,使用KB作为单位
    ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'
    ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'         //int是取整的意思
     
    应用5
    统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
    netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s ", i," ",sum[i]}'
     
    应用6
    统计/home目录下不同用户的普通文件的总数是多少?
    ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s ",i," ",sum[i]}'   
    mysql        199 
    root           374 
    统计/home目录下不同用户的普通文件的大小总size是多少?
    ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s ",i," ",sum[i]/1024/1024,"MB"}'
     
    应用7
    输出成绩表
    awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Total ";printf "------------------------------------------------------------ "}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s ",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------ ";printf "%-24s %-7s %-9s %-20s ","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s ","Avg:",math/NR,eng/NR,com/NR}' test0

    [root@localhost home]# cat test0 
    Marry   2143 78 84 77
    Jack    2321 66 78 45
    Tom     2122 48 77 71
    Mike    2537 87 97 95
    Bob     2415 40 57 62
     
    awk手册
    http://www.chinaunix.net/old_jh/7/16985.html
  • 相关阅读:
    【转】mxGraph教程-开发入门指南
    利用IPC通道进行进程间通信(C#)
    C++引用指针 & 构造函数
    MySQL配置主主及主从备份
    MySQL 主从热备份(读写分离)
    SqlServer双机热备技术实践笔记
    c#中的弱引用:WeakReference
    px、em、rem、%、vw、vh、vm这些单位的区别
    深浅clone
    JavaScript-原始值和引用值
  • 原文地址:https://www.cnblogs.com/aftree/p/9097728.html
Copyright © 2011-2022 走看看