zoukankan      html  css  js  c++  java
  • 文本处理工具awk+sed+grep

      1、awk:pattern scanning and processing language

      1)基本格式:awk 'pattern1{action1} pattern2{action2}...' filename,满足patternk则相应地执行actionk。其中,两种特殊的pattern分别是BEGIN和END。BEGIN后面的action在所有输入读入前执行,END之后的action在所有输入读入后执行。例子:

      统计第一列的总和:cat testfile | awk 'BEGIN {sum=0} {sum+=$1}END{print sum}'。

      列出UID小于10的用户名:cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1}'。和cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1}'的输出作比较,可以发现BEGIN在此处的作用(读入第一行时分隔符还是默认的空格或Tab,FS=":"在第二行才开始生效)。

      2)常用选项:-F:指定字段分割符(默认为空格和tab),因为awk是把一行分成多个字段来处理;-v var=val:将val赋给awk变量var,val可以是shell变量(需要用双引号括起来,而不能是单引号)。例子:

      查看appadmin用户所使用的bash:cat /etc/passwd | grep appadmin | awk -F ":" '{print $7}'。另有,$0表示整行,$(NF-1)表示倒数第二个字段...

      batch=1; echo "1&2&3" | awk -F '&' -v avar="$batch" '{if($1==avar) print $0}'。引用awk变量不需要$符号。

      3)内建变量:NF:当前行的字段数;NR:当前行号;FS:字段分隔符。ORS:输出记录的分隔符,默认是换行符。OFS:输出字段的分隔符,默认是空格。例子:

      查看每行各有多少字段:cat testfile |awk '{print "line " NR " has " NF " fields" }'。

      打印各个字段(事先不知道字段数):echo "path=12324&page=3&area=1" | awk -F '&' '{for(i=1; i<=NF; i++) print $i}'。

      交换列的顺序并设置列分隔符为tab:cat b|awk '{OFS=" "}{print $2, $1}'。

      指定输出分隔符:echo "192.168.1.1|Firefox|www.google.com" | awk -F '|' 'BEGIN{ORS=" "}{for(i=1;i<=NF;i++){if(i==NF)ORS=" "; print $i;} }'。这种情况下,也可以用echo "192.168.1.1|Firefox|www.google.com" | awk -F '|' '{for(i=1;i<=NF;i++){if(i==NF)print $i; else printf $i" "}}',并且只有后者适用于多行文本。

      4)内置函数(使用某些函数可能需要安装gawk,否则会提示function and never defined之类的错误):

      (1)字符串函数:

      substr(s, i [, n]):返回从下标i开始的至多n个字符的子串。如echo abcde | awk '{res=substr($0, 1, 4); print res;}'的输出为abcd。

      strtonum(str):返回str的数值。若str以0开头,则假定它是八进制的;若str以0x/0X开头,则假定它是十六进制的;否则,假定它是十进制的。如echo "da" | awk '{print strtonum("0x"$1)}'的结果为218。

      (2)位操作函数:

      and(v1, v2)返回v1和v2位与的结果。

      2、sed:stream editor(流编辑器)。
      1)语法:sed option 'script' file1 file2...,或者sed option -f scriptfile file1 file2...
      2)常用选项(option):-f:指定sed脚本;-i:(仅当使用该选项时)直接修改文件,不能用于管道;-n:不默认输出模式空间的内容(见下例);-r:使用扩展的正规表达式(括号不必转义)。
      3)脚本(script):
      形式(1):/pattern/action,即对匹配pattern的行执行action。

      形式(2):[n1[,n2]]action,对n1~n2行执行action。$表示最后一行。

      这里需要先理解模式空间(pattern space,ps)和保留空间(hold space,hs)。模式空间ps初始内容为当前处理行,而保留空间hs初始内容为空行。常用的action:

      d:删除ps的内容,并开始下一轮(行)处理;p:打印当前ps的内容(默认也会打印当前ps的内容);x:交换hs和ps的内容;h/H:将ps的内容复制/追加到hs;g/G:将hs的内容复制/追加到ps;n/N:将下一行输入内容读入/追加到ps;s:对与正则表达式匹配的ps的内容进行替换操作;a:新增行;c:取代行;i:插入行。例子:

      > cat test
      hello world
      hell world
      hel world
      he world

      > sed '/hell world/{x;p;x;p}' test
      # 解析:"/hell world"只匹配到第二行,其它行按默认输出。
      # 解析:执行第一个x后,ps与hs的内容分别为空行和"hell world";执行p打印ps,即空行;
      # 解析:执行第二个x后,ps与hs的内容分别为"hell world"和空行;执行p打印ps,即"hell world"。
      hello world    # 这是默认输出。加-n选项后不会输出,下同。
      # 空行。p的输出
      hell world    # p的输出
      hell world    # 默认输出
      hel world    # 默认输出
      he world    # 默认输出

      > sed '/hell world/{x;p}' test    # 对匹配行执行{x;p}组合
      hello world    # 默认输出
      # 空行。p的输出
      # 空行。默认输出
      hel world    # 默认输出
      he world    # 默认输出

      > sed '/hell/d;G' test    # 对每行应用"/hell/d"和"G"两个script
      # 解析:注意d会立即开始下一轮处理,所以匹配行(第1、2行)不会执行G。
      hel world    # 默认输出
      # 空行。这是G的效果:首先把hs(空行)的内容追加到ps,再默认输出ps的内容。
      he world    # 默认输出
      # 空行。G的效果

      > sed 'n;G' test    # 在偶数行之后插入空行。每三行之后加一空行:sed 'n;n;G' test
      hello world
      hell world
      # 空行
      hel world
      he world
      # 空行

      > sed 'n;d' test    # 删除偶数行
      hello world
      hel world

      > sed = test | sed 'N;s/ /     /'    # N的作用是加上行号,用于格式化输出。类似于nl命令

      1     hello world
      2     hell world
      3     hel world
      4     he world

      > sed -i 's/h/H/g' test    # 将所有行的h替换为H
      # 解析:这里空的pattern匹配所有行,g表示将匹配行的所有(而不是第一个)h替换成H。

      > sed 's/bc/-&-/' test    # 将所有行的第一个abc替换成a-bc-。&表示当前行中被匹配到的字符串。

      > sed 's/([0-9])([0-9])/-1-~2~/' test
      # 解析:将所有行的第一个324替换成-3-~2~4。"1"和"2"分别表示与第一、二个括号匹配到的内容。

      > echo "<body>Hello World</body>" | sed  's/<[^>]*>//g'    # 去掉所有HTML标签

      > cat test | sed '2a drink tea'    # 在第二行后增加新行

      > cat test | sed '2a NEW LINE 1     # 按回车键
      > NEW LINE 2'    # 承接上行。在第二行后增加2行

      > cat test | sed -e '4d' -e '2c NEW SECOND LINE'    # 使用-e连接两个及以上的script

      3、grep: print lines matching a pattern.

      1)常用选项:-x:“全行”匹配;-w:全词匹配;--exclude=GLOB:跳过名字和GLOB(通配符)匹配的文件;--include=GLOB:与exclude相反。只搜寻名字与GLOB(通配符)匹配的文件,如grep --include="*.cpp" --include="*.sh" "for" -wR *会递归地搜寻所有出现"for"的.cpp和.sh文件;-o, --only-matching:仅打印匹配到的字符串(非空),一行一个。-o可用于统计字符串的出现次数,如统计以下test.txt中hello出现的次数:grep -ow hello test.txt |wc -l

    hello hellow hello
    hello hello
    hello helloh hello hello

    不断学习中。。。

  • 相关阅读:
    Linux下环境变量配置方法梳理(.bash_profile和.bashrc的区别)
    Mac下安装配置Python2和Python3并相互切换使用
    精通Python自动化脚本
    idea之Git
    python面向对象之:细分类的组成成员
    new string("abc")创建了几个对象
    进程和线程的主要区别
    Leetcode 572 另一个树的子树
    Leetcode 二叉树的坡度
    Leetcode 559 N叉树的最大深度
  • 原文地址:https://www.cnblogs.com/hanerfan/p/3364100.html
Copyright © 2011-2022 走看看