前言:

    在服务器中对日志进行处理是十分常见的工作,所以运维对于各种文本工具来查看、分析、统计,是必备的基本工。那么学习正则表达式、grep、egrep、和tr、sort、uniq等常见的文件处理命令就十分有必要了。


1、工具分类

    文件内容:less和 cat

    文件截取:head和tail

    按列抽取:cut
    按关键字抽取:grep


2、工具集锦


2.1、文件内容查看命令:cat, tac,rev;


(1)cat


语法:

    cat [OPTION]... [FILE]...


选项:

-E: 显示行结束符$;
-n: 对显示出的每一行进行编号;
-A:显示所有控制符;
-b: 非空行编号;
-s:压缩连续的空行成一行;


(2)tac:行反向查看;


(3)rev:列反向查看;




2.2、分页查看文件内容:more、less


(1)more: 分页查看文件;


语法:

    more [OPTIONS...] FILE...


选项:

-d: 显示翻页及退出提示;



(2)less:一页一页地查看文件或STDIN输出;

查看时有用的命令包括:
    /文本: 搜索文本;
    ?文本: 搜索文本;
    n/N:跳到同向下一个 或 同向上一个匹配

注:less命令是man命令使用的分页器



2.3、显示文本前或后行内容:head、tail、tailf


(1)head


语法:

    head [OPTION]... [FILE]...

选项:

-c #: 指定获取前#字节
-n #: 指定获取前#行
-#: 指定行数


(2)tail 


语法:

    tail [OPTION]... [FILE]...

选项:

    -c #: 指定获取后#字节    
    -n #: 指定获取后#行
    -#:查看后几行;
    -f: 跟踪显示文件fd新追加的内容,常用日志监控;相当于 --follow=descriptor。
    -F: 跟踪文件名,相当于—follow=name --retry

(3)tailf

    类似tail –f,当文件不增长时并不访问文件;




2.4、按列抽取文本cut

语法:

 cut [OPTION]... [FILE]...


选项:

    -d DELIMITER: 指明分隔符,默认tab    
    -f FILEDS:
    
       FILEDS
       #: 第#个字段;
       #,#[,#]:离散的多个字段,例如1,3,6;
       #-#:连续的多个字段, 例如1-6;
       混合使用:1-3,7;
       
    -c 按字符切割;
    --output-delimiter=STRING指定输出分隔符;




示例:显示文件或STDIN数据的指定列;

    cut -d: -f1 /etc/passwd    
    cat /etc/passwd | cut -d: -f7
    cut -c2-5 /usr/share/dict/words
    
    [root@Centos6x ~]#cut -d: -f1,3 /etc/passwd
    root:0
    bin:1
    daemon:2


2.5、合并文件paste


paste:合并两个文件同行号的列到一行

语法:

    paste [OPTION]... [FILE]...


选项:

-d 分隔符:指定分隔符,默认用TAB
-s : 所有行合成一行显示


示例:

    paste f1 f2    
    paste -s f1 f2
    
    [root@Centos6x ~]#paste f1 f2
        1
    a   2
    s   3
    a   4
    a   5
    s   6
    b
    c
    d


2.6、文本数据统计: wc


作用:

 收集文本统计数据,包括计数单词总数、行总数、字节总数和字符总数。
   可以对文件或STDIN中的数据统计。


示例:

    # wc story.txt    
    39   237    1901     story.txt
    行数 单词数 字节数


常用选项:

 -l 只计数行数;
 -w 只计数单词总数;
 -c 只计数字节总数;
 -m 只计数字符总数;
 -L 显示文件中最长行的长度;



2.7、整理文本: sort

实现文本排序;把整理过的文本显示在STDOUT,不改变原始文件。

语法:

    sort [options] file(s)


常用选项:

 -r 执行反方向(由上至下)整理;
 -n 执行按数字大小整理;
 -f 选项忽略( fold)字符串中的字符大小写;
 -u 选项(独特, unique)删除输出中的重复行;
 -t c 选项使用c做为字段界定符;
 -k X 选项按照使用c字符分隔的X列来整理;能够使用多次;


2.8、唯一性处理:uniq


从输入中删除前后相接的重复的行。



语法:

 uniq [OPTION]... [FILE]...



选项:

-c: 显示每行重复出现的次数;
-d: 仅显示重复过的行;
-u: 仅显示不曾重复的行;连续且完全相同方为重复;



uniq命令常和sort 命令一起配合使用:
    sort userlist.txt | uniq -c



2.9、比较文件: diff


比较两个文件之间的区别:

    diff foo.conf foo2.conf    
    
    5c5
    < use_widgets = no
    ---
    > use_widgets = yes    / 注明第5行有区别(改变)/



 diff:命令的输出被保存在一种叫做“补丁”的文件中;
 使用 -u 选项来输出“统一的( unified)” diff格式文件,最适用于补丁文件。

2.10、patch


patch:复制在其它文件中进行的改变(要谨慎使用)。


选项:

-b 选项来自动备份改变了的文件


示例:

$ diff -u foo.conf foo2.conf > foo.patch;
$ patch -b foo.conf foo.patch    /使用之前先备份foo.conf文件/;



3、文本三剑客——grep命令


Linux文本处理三剑客:grep、sed、awk;

   grep:文本过滤(模式: pattern)工具;grep, egrep, fgrep(不支持正则表达式搜索)。
 sed: stream editor,文本编辑工具。
 awk: Linux上的实现gawk,文本报告生成器。



grep: Global search REgular expression and Print out the line。

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

模式(PATTERN):由正则表达式元字符及文本字符所编写的过滤条件。


语法:

grep [OPTIONS] PATTERN [FILE...]

示例:

grep root /etc/passwd
grep "$USER" /etc/passwd
grep '$USER' /etc/passwd
grep `whoami` /etc/passwd



命令选项:

    --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:使用ERE,支持扩展的正则表达式。。
    -F:相当于fgrep,不支持正则表达式。


4、正则表达式(REGEX)


REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能。
程序支持: grep,sed,awk,vim, less,nginx,varnish等


正则表达式分类:

    基本正则表达式: BRE;
    扩展正则表达式: ERE;


正则表达式引擎:

    采用不同算法,检查处理正则表达式的软件模块;
    PCRE( Perl Compatible Regular Expressions)


元字符分类:字符匹配、匹配次数、位置锚定、分组;
正则表达式man帮助获取:man 7 regex



4.1、基本正则表达式元字符


4.1.1、字符匹配


.  匹配任意单个字符
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母 [:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字 [:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号


4.1.2、匹配次数



匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数。


* 匹配前面的字符任意次,包括0次。贪婪模式,尽可能长的匹配。
.* 任意长度的任意字符
\? 匹配其前面的字符0或1次
\+ 匹配其前面的字符至少1次
\{n\} 匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次
\{,n\} 匹配前面的字符至多n次
\{n,\} 匹配前面的字符至少n次


4.1.3、位置锚定


位置锚定:定位出现的位置。


^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 词首锚定,用于单词模式的左侧
\> 或 \b 词尾锚定;用于单词模式的右侧
\ 匹配整个单词


4.1.4、分组及后向引用


分组: \(\) 将一个或多个字符捆绑在一起,当作一个整体进行处理,如: \(root\)\+


分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...。
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;


 示例:

    \(string1\+\(string2\)*\)
    \1 : string1\+\(string2\)*
    \2 : string2


后向引用:引用前面的分组括号中的模式所匹配字符, 而非模式本身


或者: \|

示例: a\|b: a或b C\|cat: C或cat \(C\|c\)at:Cat或cat




5、egrep及扩展的正则表达式

egrep = grep -E

语法:

    egrep [OPTIONS] PATTERN [FILE...]


扩展正则表达式的元字符:

字符匹配:

    . 任意单个字符    
    [] 指定范围的字符
    [^] 不在指定范围的字符



次数匹配:

    *:匹配前面字符任意次    
    ?: 0或1次+: 1次或多次
    {m}:匹配m次
    {m,n}:至少m,至多n次


位置锚定:

    ^ :行首    
    $ :行尾
    \<, \b :语首
    \>, \b :语尾



分组及后向引用:

    ():    
    后向引用: \1, \2, ...


或者:|

    a|b: a或b    
    C|cat: C或cat
    (C|c)at:Cat或cat