在前面介绍了linux中重要的几个文本编辑工具,如vim/vi、nano等等,它们都可以进行文本文件内容的编辑操作,接下来介绍的是文本的处理工具:

主要有grep家族,sed,awk等等,还有一些其他的处理工具诸如cut sort等等了;作为文本处理工具的三剑客之一,grep可谓功能强大。grep 全称是 (Global search REgular expression and Print line)

作用是:文本搜索工具,根据用户指定的文本模式(正则表达元字符以及正常字符组合而成)对目标文件进行逐行搜索,显示能匹配到的行;    

模式:由正则表达式的原字符及文本字符所编写的过滤条件;

grep家族里根据元字符的数量及功能不同又分为基本正则表达式(grep)和拓展正则表达式(egrep)

用法上有些许的差异,但是也能互通,比如 grep -E 就相当于egrep了

 注意:grep默认仅支持基本的正则表达式

     egrep默认仅支持扩展的正则表达式

     fgrep默认不开启正则表达式引擎

用法格式:grep [options] PATTERN [FILE...]

【常用选项】:

        -i, --ignore-case

           忽略PATTERN 和输入文件中的大小写的分别。

        -v, --invert-match

           改变匹配的意义,只选择不匹配的行。反向匹配 

        -c,--count

           计数,统计匹配PATTERN

        -o, --only-matching

           关闭贪婪模式  只显示匹配的行中与 PATTERN 相匹配的部分。    

        -q, --quiet, --silent

           不输出任何匹配结果


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

        -F,--fixed-strings, --fixed-regexp: 相当于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, --before-context=NUM  在显示匹配PATTERN的行的同时 显示其前面和后面各NUM行

  

PATTERN:指的是过滤条件,正则表达式由两种基本字符类型组成:原义(正常)文本字符和元字符。   文本字符呢,就是代表其本身含义的字符这个不用做太多解释;

  而所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,不表示其字面意义,而

用于额外功能性描述。这些元字符会被正则表达式的引擎解释为特殊含义;   

     

基本的正则表达式元字符:

1.字符匹配:

  . : 匹配任意单个字符  grep .x /etc/passwd 只要包含x就作匹配

  [] : 匹配指定范围内的任意单个字符  grep [xhm] /etc/passwd 匹配文件中带有x或h或m的字段

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

这里类似于前面提到的Globbing通配字符,例如[[:digit:]]表示的匹配单个数字等等;这里就不作赘述;


2.次数匹配:该类字符之前的那个字符可以出现的次数

  *:前面的字符可以出现任意次(0,1或多次) grep 'x*y' /FILE 文件中y之前出现x的次数不限

  \?:前面的字符可有可无(0或1次) grep  'x\?y' /FILE 文件中y之前的x最多出现1次

  \+:前面的字符至少出行1次(1次或多次) grep  'x\+y' /FILE 文件中y之前的x最少出行1次

  \{m\}:前面的字符必须出现m次    grep  '\{2\}' /FILE 文件中y之前的x只能出现2次

  \{m,n\}:前面的字符出现至少出现m次 至多n次 所以通常来讲 m<n

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

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


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

 grep '.*y' /FILE  文件中y之前无论出现什么字符都匹配


3.位置锚定字符:

 行锚定:

  行首锚定:^ grep '^s' /FILE  文件FILE中以s开头的行

  行尾锚定:$ grep 's$' /FILE  文件中以s结尾的行

 字锚定:

  字首锚定:\< 或者 \b 

  字尾锚定:\> 或者 \b


  grep -o '\<y.*c\>' whj.txt 显示whj.txt中 y字母开头c字母结尾的字


  \b:旧版本中的锚定方法;

**对于正则表达式的引擎来说,所谓的字是由非特殊字符组成的连续字符串;

4.分组与引用字符:


 \(PATTERN\) 将此PATTERN所匹配到的字符当作一个不可分割 的整体来处理


 在正则表达式引擎中,有一系列的内置变量,这些变量会保存所有分组内的字符信息,用于后向引  用,这些变量依次是:

 \1 \2 \3 ……

 例如 在PATTERN1\(PA2\)PA3\(PA4\)... 之中,\1:pattren2 \2:pattern4...

 也就是\1表示第一组小括号内的PATTERN匹配到的字符;...以此类推


 例:找出在/etc/passwd 中用户的uid和gid相同的用户账户;

    grep '\(\<[[:digit:]]\+\>\).*\1' /etc/passwd

5.或:

\| 


注意:\|将其左右两边的字符串当作整体对待;

A\|american : A或amarican


例题

 请找出ifconfig的执行结果中,数字在100-255之间的三位数

 第一位:1  或者      2

 第二位:0-9或者 0-4 或者  5

 第三位:0-9或者 0-9 或者 0-5


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


 找出0-255:

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


grep [options] [-e PATTERN | -f FILE] [FILE...] 

默认情况下,grep命令后只允许有一个PATTERN,如果想要在一次grep搜索过程中写多个PATTERN 需要使用-e选项;每个-e 只能跟一个PATTERN


或者将所需要的PATTERN写入到一个文件中保证每行只有一个PATTERN,这样可以使用-f FILE 来实现多PATTERN匹配

   egrep:

    grep [options] PATTERN [FILE...]

      扩展的正则表达式元字符

       1.字符匹配

         .

         []

         [^]

       2.次数匹配

         *

         ?

         +

         {m}

         {m,n}

         {m,}

         {0,n}

        3.位置锚定

          ^

          $

          \<,\b

          \>,\b

        4.分组和引用

         (pattern)

         \1  \2  \3 ...

        5.或:

          |

       以上可以看出,egrep相比grep 少了很多'\',但是注意位置锚定中的字首字尾锚定不能省略'\'


   fgrep

      不使用PATTERN搜索引擎,所以 PATTERN所有的字符都被当作文本字符来处理;

其他的文本处理命令

  wc:

   wc [opt]... [file]...

     -l:只显示行数

     -w:只显示字数

     -c:只显示字符数

     -m:

  cut:

   把文件某一行的某些字段移除;

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


   【OPT】

    -d,--delimeter=DELIM

      指定在修剪时,所依赖的分隔符 默认 是空白字符

    -f,--filed=LIST

      根据定义的分隔符来指定字段的编号

      地址定界的使用方法:

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

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

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


     --output-delimeter=STRING :指定输出分隔符

  awk:

    awk -F "DELIMETER" '[/PATTERN/]{print $1,$2,...$NF}

      -F "DE" :指定字段分隔符,默认为空白字符;

      $1 $2...$NF : 根据字段分割符切割出来的文本片段都存放在相应的内部变量中;

  sort:

    将文本文件按行排序,默认排序规则是按照ASCII表进行,这个排序标准可以修改;

    -r  逆序排序.

    -R  随机排序,这种随机算法非常简单,不适用于复杂环境;

    -u  重复出现的行,只保留一行,连续且完全相同的行才是重复的行,祛重.

    -n  按数值大小进行排序.

    -t  指定字段分隔符.

    -k  指明根据哪个关键字段进行排序,一般和-t同时使用.


  uniq:

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

    -u  只显示不重复的行

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


  diff:比较两个文件的差异性

   同一个文件的不同修改版本。打补丁:


  patch:apply changes to files

    patch [-R][-i patchfile] [file]



例题:

有一个文件a.txt,内容如下:

  12 314 56 78

  24 56 8 90

  76 11 67 87

  100 89 78 99

找出文件中的最大和最小值;

最大值:cat a.txt | tr ' ' '\n' | sort -nr | head -1

最小值:cat a.txt | tr ' ' '\n' | sort -n | head -1