文本处理工具基础(grep系、sed、awk等)

常用的文本编辑工具有vim、vi、nano,同时文本处理工具还有文本处理三剑客:grep系、sed、awk,具体介绍如下。

1、grep系

grep系是文本搜索工具,可以分为grep、egrep、fgrep,是基于“PATTERN”对于给定的文本进行模糊搜索,同时grep系默认工作于贪婪模式下。

(1)grep:Global search Regular expression and Print out the line(利用正则表达式进行全局搜索,并将匹配的行显示出来)

  grep的格式一为:grep [OPTION] PATTERN [FILE……]

  格式中的PATTERN,是过滤条件,是正则表达式元字符以及没有特殊含义的文本字符组成。正则表达式的元字符,其会被正则表达式引擎解释为特殊含义;最完整的的正则表达式引擎为pcre(perl common regular expression),即perl语言的正则表达式引擎。 对于正则表达式引擎来说,字是由非特殊字符组成的连续字符串。

  正则表达式的元字符分为两类:基本的正则表达式BRE、扩展得到正则表达式ERE。grep默认仅支持基本的正则表达式,egrep默认支持扩展正则表达式,fgrep默认不开启正则表达式引擎。其中的文本字符,是只具备字符表面的那些字母。   

  grep命令的常用选项为:-i,--ignore-case:忽略文本字符的大小写

                       -v,--invert-match:反向匹配,最终显示的结果是PATTERN不能成功匹配的行

                       -c,--count:计数,统计匹配PATTERN的所有行数

                       -o,--only-matching:关闭贪婪模式,仅显示PATTERN能够匹配的内容

                       -q,--quiet,--silent:安静模式,不输出任何匹配结果(判断有无这样的信息,只关注有无和模式匹配的内容)

                       --color[=WHEN],--colour[=WHEN]:将匹配PATTERN的内容进行高亮显示,常用--color=auto

                       -E,--extended-regexp:扩展的正则表达式,grep -E相当于egrep

                       -F,--fixed-strings,--fixed-regexp:grep -F相当于fgrep

                       -G,--basic-regexp:基本正则表达式,egrep -G相当于grep

                       -P,--perl-regexp:使用PCRE引擎

                       -A NUM,--after-context=NUM:在显示匹配PATTERN的行的同时显示其后面的NUM行

                       -B NUM,--before-context=NUM:在显示匹配PATTERN的行的同时显示其前面的NUM行

                       -C NUM,-NUM,--context=NUM:在显示匹配PATTERN的行的同时显示其前后的NUM行

 例如:# grep "^root\>"  /etc/passwd : 在/etc/passwd中查找并显示用户名为“root”用户的信息

       # grep -n "little" /etc/group :查找并显示在/etc/group中"little"所在的行和行号

       # grep -v "^root\>"  /etc/passwd : 在/etc/passwd中查找并显示除了“root”之外的所有用户的信息  (结果中的一部分)

       # grep -o "little" /etc/group :在/etc/group中查找"little"

       # grep -i 'o' /var/log/boot.log :在/var/log/boot.log查找字母"o"和"O"所在的行

       # grep -E "t{2,}"  /etc/rc.d/init.d/network :在/etc/rc.d/init.d/network中查找并显示"t"至少出现2次所匹配的行

       # grep -A 2 "/dev/shm"  /etc/fstab :在/etc/fstab中查找并显示"/dev/shm "所匹配的行以及下2行

       # grep -B 1 "order " etc/host.conf :在/etc/host.conf 中查找并显示"order "所匹配的行以及上1行

       # grep -C 1 "MemFree" /proc/meminfo :在/proc/meminfo查找"MemFree"所在的行以及上一行和下一行



 PATTERN是正则表达式元字符。基本的正则表达式元字符为GLOBBING,简化版的正则表达式有[]、?、*

 grep字符匹配如下:

    .:匹配任意单个个字符

    []:匹配任意范围内的单个字符

    [^]:匹配指定范围以外的任意单个字符

    [:lower:]:所有的小写字母

    [:upper:]:所有的大写字母

    [:alpha:]:表示所有的字母字符

    [:digit:]:表示所有的十进制数字

    [:space:]:表示空白字符

    [:alnum:]:表示所有的大小写字母以及十进制数字

    [:punct:]:所有的标点符号

    [:xdigt:] :显示所有打的十六进制数字

    a~z:所有的小写字母

    A~Z:所有的大写字母

    0~9:表示所有的十进制数字

 例如:# echo "Aa12@" | grep "[[:alpha:]]"  :显示"Aa12@"中的字母不区分大小写

       # echo " A a12@" | grep "[[:space:]]" :显示"A a12@"中的空白字符

       # ls -l | grep "r..r" :显示r开头和结尾的内容,其中 . 表示任意单个字符

       # echo "hello little525" | grep "[0-9]"

       # echo "hello little525" | grep "[^0-9]"

       # grep -c "^[[:space:]]*&" little

 下列所有的字符集都可以放置于[]之中用于匹配单个字符;次数匹配,解释为该类字符之前的那个字符可以出现的次数,具体字符如下:

    *:其前面的字符可以出现任意次(0次、1次或多次)

    \?:其前面的字符可以有可以无(0次或1次)

    \+: 其前面的字符至少出现1次

    \{m\}:其前面的字符必须出现m次

    \{m,n\}:其前面的字符至少出现m次,至多出现n次(m<n)

    \{,n\}:其前面的字符至少出现0次,至多出现n次

    \{m,\}:其前面的字符至少出现m次,至多不限

    .* :在正则表达式中,表示任意长度,任意字符的方式

 例如:# echo "root" | grep "o*"  :匹配其前的o任意次  

       # echo "root" | grep "o\?" :匹配o2次, \?:匹配其前的字符0次或1次

       # echo "rooot" | grep "o\?" :匹配o3次

       # echo "root" | grep ".*" :匹配其前的任意字符任意次

       # echo "root" | grep "o\{2\}*"  :"o"出现2次

       # echo "rooot" | grep "o\{3,\}*"  :"o"至少出现3次


 grep位置锚定字符如下,其中,\b表示旧版本中的锚定方法:

    行锚定:行首锚定^ ;行尾锚定$

    字锚定:字首锚定 \<或\b ;字尾锚定 \>或\b

 例如:'^\<root\>' 和^\[[:digit:]]\{2\}\>'

       # cat /etc/passwd | grep "^z.*"  :查找并显示以"z"开头的用户的所有信息

       # cat /etc/rc.d/rc.sysinit | grep -n "^$" :显示以"n"为行尾的所有用户组的信息

       # grep -n "\<little\>" /etc/passwd :显示用户名为little的所有信息

       # grep -n "bash\>$" /etc/passwd :显示shell为/bin/bash的所有用户

       # ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|(1[0-9]{2}|2[0-1][0-9]|22[0-3]))\.([0-9][1-9]{2}|(1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))\>"


 分组与引用字符为\(PATTERN\);将此PATTERN所匹配到的所有字符当做一个不可分割的整体来处理,在正则表达式引擎中,有一系列的内置变量,这些变量会保存所有分组内的字符信息,用于后项引用,这些变量依次是\2、\3、\4…… 例如至少要匹配一次xy表达为\(xy\)\+

  多分组的例子pattern1\(pattern2\)pattern3\(pattern4\(pattern5\)\)中,其中,第一个小括号  \1:表示pattern2;\2:表示pattern4;\3:表示pattern5。例子中\1:表示第一组小括号中的PATTERN匹配到的字符;\2:表示第二组小括号中的PATTERN匹配到的字符……

  grep引用字符的例子:请找出在/etc/passwd中用户的UID和GID相同的用户账户:# grep '\(\<[[:digit:]]\+\>\).*\1' /etc/passwd

 grep的或字符为:\|

  注意:\| 将其左右两边的字符串当做整体来对待。例如:A\|american,即A或american

  grep或字符的例子:请找出ifconfig命令的执行结果中数值在100~255之间的整数:第一位可以为1和2;第二位中,如果第一位为1,则第二位可以为0~9;若第一位为2,第二位有0~4和0~5两种情况;若第一位为1,第二位为0~9,则第三位可以为0~9;若第一位为2,第二位为0~4,则第三位可以为0~9;若第一位为2,第二位为5,则第三位可以为0~5。

   # ifconfig | grep '\<\(1[0~9][0~9]\|2[0~4][0~9]\|25[0~5]\)\>'

  

 grep的格式二为:grep [OPTION] [-e PATTERN | -f FILE] [FILE……]

   在默认情况下,grep后面只允许有一个PATTERN,如果想在一次grep中写多个PATTERN,则需要用-e选项,每一个-e选项只能使用一个PATTERN作为参数。要将所需要的PATTERN写入一个文件中,保证每行只有一个PATTERN,我们就可以使用-f FILE方式来实现多PATTERN的匹配。

 例如:(1)、# ls -l | grep '^a':通过管道过滤ls -l输出的内容,只显示以a开头的行

       (2)、# grep 'test' d*:显示所有以d开头的文件中包含test的行

       (3)、# grep 'test' aa bb cc:显示在aa,bb,cc文件中匹配test的行

       (4)、# grep '[a-z]\{5\}' aa:显示所有包含每个字符串有5个连续小写字符的字符串的行

       (5)、# grep "a|b" :匹配包含字符样式为"a|b"的行


  

 (2)egrep

 egrep的格式为:egrep [OPTION] PATTERN [FILE……]

 egrep扩展的正则表达式字符如下,和grep相比egrep少了很多\,书写起来比较方便:

 字符匹配:. [] [^]

 次数匹配:* ? + (m) (m,n) (m,) (0,n)

 位置锚定:^ $ \<,\b \>,\b

 分组与引用:() \1,\2,\3……

 或:|

 例如:# grep -E "a|b" :匹配包含字符样式为"a"或"b"的行

       # egrep -i --color=auto 'o' /var/log/boot.log :在/var/log/boot.log查找字母"o"和"O"所在的行

       # egrep --color=auto -n "^ro+" /etc/passwd :查找以r开头后面至少有一个o的用户所在的行


 (3)fgrep

 fgrep的PATTERN中所有的字符都被当做文本字符来处理


 


2、sed:stream EDitor,即流编辑器。

sed是一种行编辑器,其是在执行时被改变,其原数据不变。

3、awk

awk格式为:awk -F "DELIMITER" '[\PATTERN\]{print $1,$2,$3,……$NF}' FILE……

其中,-F "DELIMITER":是指定字段分隔符,其默认为空白字符。$1,$2,$3,……$NF:根据字段分隔符切割出来的文本片段都存放在相应的内部变量中

gawk即GNU awk,gawk在Linux中用的最多。awk是一种文本格式化工具、文本报告生产器,也叫做文本处理的编程语言。

例如:# awk -F : 'print $NF' /etc/passwd

      # df | tr -s ' ' |cut -d ' ' -f6   (tr为格式转换,例如:tr '\n' ',')


另有其他的文本处理命令:wc、cut、sort、uniq、diff、patch等,具体解释如下:

 wc命令

 wc的格式为:wc [OPTION]…… [FILE……]

 -l:只显示行数

 -w:只显示字数

 -c:只显示字符数

 例如:# wc -l install.log

       # wc last | ec -l

 

 cut命令:remove sections from each line of files

 能够被cut命令修剪的文件,一般都是具有一定结构或格式的文本文档,如/etc/passwd

 cut格式为:cut [OPTION]…… [FILE……]

  -d,delimiter=DELIM:指定在实施修剪操作时所依赖的分隔符,默认是空白字符

  -f,--fields=LIST:根据定义的分隔符来指定字段的编号

  --output-delimiter=STRING:指定输出分隔符,自定义

 cut中地址定界的使用方法如下:

        #:选择被指定的单个字段

        #,#:离散的多个被指定的单个字段

        #-#:连续的多个被指定的字段


sort命令:sort line of text files 

sort命令是将文本文件按行继续排序,默认排序方式是按照ASCII码表中字符顺序进行,这个排序标准可以修改。

-R,--random-sort:随机排序,这种随机算法是非常简陋的,不适合用在复杂环境

-r,--reverce:排序后倒序排序

-u,--unique:去重,重复出现的行,只保留1行,连续且完全相同的叫做重复

-n,--numeric-sort:以数字的数值大小进行排序

-t,--field-separator=SEP:指定字段分隔符

-k,--key=KEYDEF:指明根据哪一个关键字段进行排序,一般和-t一起进行使用


uniq命令:report or omit repeated lines

-d,--repeated:只显示重复出现的行,而且每一组重复行只显示一行

-u,--unique:只显示不重复的行

-c,--count:在每行以前缀的方式显示重复行的重复次数


diff命令: compare files line by line

diff命令是同一文件的不同修改版本:相当于打补丁机制


patch命令:apply changes to files

 patch格式为:patch [-R][-i patchfile]

 -R:恢复还原补丁文件 例如:# patch -R -i name.patch name

其中,diff和patch是一组同时使用的命令。


     本文转自little_ding 51CTO博客,原文链接:http://blog.51cto.com/12496428/1914997,如需转载请自行联系原作者







上一篇:CUDA学习(十)


下一篇:数据库设计中的14个技巧(转载)