zoukankan      html  css  js  c++  java
  • awk与sed区别

    引用:linux工具快速教程:https://linuxtools-rst.readthedocs.io/zh_CN/latest/index.html#

    1、sed 文本替换利器

    首处替换
    sed 's/text/replace_text/' file //替换每一行的第一处匹配的text
    
    全局替换
    sed 's/text/replace_text/g' file
    
    默认替换后,输出替换后的内容,如果需要直接替换原文件,使用-i::
    sed -i 's/text/repalce_text/g' file
    
    移除空白行
    sed '/^$/d' file
    
    变量转换,已匹配的字符串通过标记&来引用.
    echo this is en example | sed 's/w+/[&]/g'
    结果:[this] [is] [en] [example]
    
    子串匹配标记,第一个匹配的括号内容使用标记 1 来引用
    sed 's/hello([0-9])/1/'
    
    双引号求值
    sed通常用单引号来引用;也可使用双引号,使用双引号后,双引号会对表达式求值
    sed 's/$var/HLLOE/'
    
    当使用双引号时,我们可以在sed样式和替换字符串中指定变量;
    eg:
    p=patten
    r=replaced
    echo "line con a patten" | sed "s/$p/$r/g"
    结果:line con a replaced
    
    其它示例
    字符串插入字符:将文本中每行内容(ABCDEF) 转换为 (ABC/DEF)
    sed 's/^.{3}/&//g' file

    2、awk 数据流处理工具

    1) awk脚本结构
    
        awk ' BEGIN{ statements } statements2 END{ statements } '
    
    工作方式
        1.执行begin中语句块;
        2.从文件或stdin中读入一行,然后执行statements2,重复这个过程,直到文件全部被读取完毕;
        3.执行end语句块;
    2)print 打印当前行
    
    使用不带参数的print时,会打印当前行
        echo -e "line1
    line2" | awk 'BEGIN{print "start"} {print } END{ print "End" }'
    
    print 以逗号分割时,参数以空格定界;
        echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; 
        print var1, var2 , var3; }'
        $>v1 V2 v3
    
    使用-拼接符的方式(""作为拼接符);
        echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; 
        print var1"-"var2"-"var3; }'
        $>v1-V2-v3

    3)特殊变量: NR NF $0 $1 $2

      NR:表示记录数量,在执行过程中对应当前行号;

      NF:表示字段数量,在执行过程总对应当前行的字段数;

      $0:这个变量包含执行过程中当前行的文本内容;

      $1:第一个字段的文本内容;

      $2:第二个字段的文本内容;

    echo -e "line1 f2 f3
     line2 
     line 3" | awk '{print NR":"$0"-"$1"-"$2}'
    
    打印每一行的第二和第三个字段
        awk '{print $2, $3}' file
    
    统计文件的行数
        awk ' END {print NR}' file
    
    累加每一行的第一个字段
        echo -e "1
     2
     3
     4
    " | awk 'BEGIN{num = 0 ; 
        print "begin";} {sum += $1;} END {print "=="; print sum }'
    4)传递外部变量
        var=1000
        echo | awk '{print vara}' vara=$var #  输入来自stdin
        awk '{print vara}' vara=$var file # 输入来自文件
    
    5)用样式对awk处理的行进行过滤
        awk 'NR < 5' #行号小于5
        awk 'NR==1,NR==4 {print}' file #行号等于1和4的打印出来
        awk '/linux/' #包含linux文本的行(可以用正则表达式来指定,超级强大)
        awk '!/linux/' #不包含linux文本的行
    
    6)设置定界符
    使用-F来设置定界符(默认为空格
        awk -F: '{print $NF}' /etc/passwd
    
    7)读取命令输出
    使用getline,将外部shell命令的输出读入到变量cmdout中::
    
        echo | awk '{"grep root /etc/passwd" | getline cmdout; print cmdout }'
    8)在awk中使用循环
    
        for(i=0;i<10;i++){print $i;}
        for(i in array){print array[i];}
    
    eg:以下字符串,打印出其中的时间串::
    
        2015_04_02 20:20:08: mysqli connect failed, please check connect info
        $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F ":" '{ for(i=1;i<=;i++) printf("%s:",$i)}'
        >2015_04_02 20:20:08:  # 这种方式会将最后一个冒号打印出来
        $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F':' '{print $1 ":" $2 ":" $3; }'
        >2015_04_02 20:20:08   # 这种方式满足需求
    
    而如果需要将后面的部分也打印出来(时间部分和后文分开打印)::
    
        $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F':' '{print $1 ":" $2 ":" $3; print $4;}'
        >2015_04_02 20:20:08
        >mysqli connect failed, please check connect info
    
    以逆序的形式打印行:(tac命令的实现)::
    
        seq 9| 
        awk '{lifo[NR] = $0; lno=NR} 
        END{ for(;lno>-1;lno--){print lifo[lno];}
        } '
    9)awk结合grep找到指定的服务,然后将其kill掉
        ps -fe| grep msv8 | grep -v MFORWARD | awk '{print $2}' | xargs kill -9;
    
    10)awk实现head、tail命令
    
    head
        awk 'NR<=10{print}' filename
    
     tail
        awk '{buffer[NR%10] = $0;} END{for(i=0;i<11;i++){ 
        print buffer[i %10]} } ' filename
    
    11)打印指定列
    awk方式实现
        ls -lrt | awk '{print $6}'
    
    cut方式实现
        ls -lrt | cut -f6
    
    12)打印指定文本区域
    确定行号
        seq 100| awk 'NR==4,NR==6{print}'
    
    确定文本
    打印处于start_pattern 和end_pattern之间的文本::
        awk '/start_pattern/, /end_pattern/' filename
    
    示例::
    
        seq 100 | awk '/13/,/15/'
        cat /etc/passwd| awk '/mai.*mail/,/news.*news/'
    13)awk常用内建函数
    
    index(string,search_string):返回search_string在string中出现的位置
    sub(regex,replacement_str,string):将正则匹配到的第一处内容替换为replacement_str;
    match(regex,string):检查正则表达式是否能够匹配字符串;
    length(string):返回字符串长度
    
        echo | awk '{"grep root /etc/passwd" | getline cmdout; print length(cmdout) }'
    
    printf 类似c语言中的printf,对输出进行格式化::
    
        seq 10 | awk '{printf "->%4s
    ", $1}'
    
    14)迭代文件中的行、单词和字符
    
    迭代文件中的每一行
    
    while 循环法
    
        while read line;
        do
        echo $line;
        done < file.txt
    
        改成子shell:
        cat file.txt | (while read line;do echo $line;done)
    
    
    awk法
    
        cat file.txt| awk '{print}'
    
    迭代一行中的每一个单词
    
        for word in $line;
        do
        echo $word;
        done
    
    
    迭代每一个字符
    ${string:start_pos:num_of_chars}:从字符串中提取一个字符;(bash文本切片)
    
    ${#word}:返回变量word的长度
    
        for((i=0;i<${#word};i++))
        do
        echo ${word:i:1);
        done
    
    
    以ASCII字符显示文件
    
        $od -c filename
  • 相关阅读:
    音频重采样48kk转16k
    ld: symbol(s) not found for architecture x86_64问题解决
    麦克风啸叫抑制解决方案之移频法
    gcc makefile 模板
    mysql 分组加序号
    java微信公众号JSAPI支付以及所遇到的坑
    appium新手入门(1)—— appium介绍
    一次完整的JVM堆外内存泄漏故障排查记录
    mysql 批量更改表名
    爬虫技术
  • 原文地址:https://www.cnblogs.com/ggzhangxiaochao/p/13385751.html
Copyright © 2011-2022 走看看