• Shell编程基础教程5--文本过滤、正则表达式、相关命令


    5.文本过滤、正则表达式、相关命令
        5.1.正则表达式(什么是正则表达式?正则表达式怎么进行匹配?常用命令)
            简介:
                一种用来描述文本模式的特殊语法
                由普通字符(例如字符a到z)以及特殊字符(成为元字符,如/、*、?等)组成
                匹配的字符串
                文本过滤工具在某种情况下都支持正则表达式
            基本元字符集及其含义
                ^    只匹配行首,例子 ^a 表示匹配以a开头的
                $    只匹配行尾,例子 txt$ 表示匹配以txt结尾的
                *    匹配0或多个此单字符,
                []    只匹配[]内的字符。可以是一个单字符,也可以是字符序列。可以使用-表示[]内字符序列范围,如用[1-5]代表[12345]
                    只用来屏蔽一个元字符的特殊含义,例子 * 可以屏蔽*作为元字符的含义,使其就表示*字符本身,$、^等等例子
                .    只匹配任意单字符
                pattern{n}    只用来匹配前面pattern出现次数。n为次数
                pattern{n,}    含义同上,但是次数最少为n
                pattern{n,m}    含义同上,但是pattern出现次数在n与m之间
            例子
                . 可以匹配任意单字符
                    ...x..x..x
                        drwxrwxrw-    不匹配
                        -rw-rw-rw-    不匹配
                        -rwxr-xr-x    匹配
                        -rwxrwxrwx    匹配
                    ....XC....
                        3452XC763D    匹配
                        4352XC433    不匹配
                        3452XD7654    不匹配
                ^ 只允许在一行的开始匹配字符或单词
                    ^d
                        drwxrwxrw-    匹配
                        -rwxrwxr-x    不匹配
                    ^...1
                        3482XC763D    不匹配
                        23DDDDxs11    不匹配
                        3451XD7633    匹配
                        3D11XC9871    匹配
                $ 与 ^ 正相反,它在行尾匹配字符串或字符,$符号放在匹配单词后面
                    trouble$    匹配以单词trouble结尾的所有字符
                    ^$        匹配空行
                    ^.$        匹配只含有一个字符的行
                * 可以匹配任意字符0次或多次重复表达
                    10133*1
                        101331        匹配
                        10133921    匹配
                        10133As1    匹配
                 用于屏蔽一个特殊字符
                    特殊字符有",',||,^,*,+等等,元字符基本都是特殊字符
                    *.pas        该正则表达式匹配以*.pas结尾的所有字符或文件
                [] 用于匹配一个范围或集合
                    逗号将括号内要匹配的不同字符串分开
                    用 - 表示一个字符串范围,表明字符串范围从 - 左边字符开始,到 - 右边字符结束
                    例子
                        [0123456789]或[0-9]        假定要匹配任意一个数字
                        [a-z]    任意小写字母
                        [A-Za-z]    任意大小写字母
                        [A-Za-z0-9]        匹配任意字母或数字
                        [S,s]    匹配大小写s
                {} 用于匹配模式结果出现的次数
                    A{2}B        A出现2次,AAB
                    A{4,}B    A至少出现4次,AAAAB、AAAAAB……
                    A{2,4}B    A出此案次数为2到4次,AAB、AAAB、AAAAB
                    [0-9]{3}.[0-9]{3}.[0-9]{3}.[0-9]{3}    匹配IP地址
        5.2.find介绍(文件查找)
            简介
                一个查找命令
                查找具有某些特征文件的命令
                可遍历当前目录甚至整个文件系统来查找某些文件或目录
                遍历大的文件系统时,因为耗时比较长,一般放在后台执行,并将结果重定向到一个文件
            命令格式
                find pathname -options [-print -exec -ok]
                    pathname    find命令所查找的目录路径。例如用.表示当前目录,用/来表示系统根目录
                    -print    find命令将匹配的文件输出到标准输出
                    -exec    find命令将匹配的文件执行该参数所给出的shell命令,相应命令的形式为 command {} ; 。注意{}和;之间的空格
                    -ok和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出体术,让用户来确定是否执行
            find的命令选项
                -name    按照文件名查找文件
                -perm    按照文件权限来查找文件
                -user    按照文件属主来查找文件
                -group    按照文件所属的组来查找文件
                -mtime -n +n    按照文件的更改时间来查找文件,-n表示文件更改时间距离现在n天以内, +n 表示文件更改时间距离现在n天以前。find命令还有-atime和-ctime选项,但是它们都和-mtime选项相似
                -size n[c]    查找文件长度为n块的文件,带有 c 时表示文件长度以字节计
                -nogroup    查找无有效所属组的文件,即该文件所述的组在/etc/groups中不存在
                -nouser        查找无有效数组的文件,即该文件的属主在/etc/passwd中不存在
                -newer "file1" ! -newer "file2"        查找更改时间比文件file1新但是比file2旧的文件
                -type    查找某一类型的文件,例如:
                    b    块设备文件
                    d    目录
                    c    字符设备文件
                    p    管道文件
                    l    符号链接文件
                    f    普通文件
                man find 来查看更多更为详细的关于find命令的信息
            示例:
                使用name选项
                    可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来
                    find -name "*.txt" -print        没写任何路径,就是默认当前路径
                    find ./ -name "*.txt" -print
                    find ./ -name "[A-Z]*" -print
                    find /etc -name "host*" -print
                使用perm选项
                    find ./ -perm 755 -print
                使用user和nouser选项
                    find `pwd` -user root -print    反引号里的命令,`pwd`表示执行pwd命令获取的路径作为find查找的路径
                    find / -nouser -print
                    nohup find / -nouser -print > nouser.log    在后台执行(使用nohup)find命令,并将结果重定向到nouser.log文件中
                使用group和nogroup
                    find ./ -group perfect -print
                    find / -nogroup -print
                按照更改时间查找文件
                    find /var -mtime -5 -print
                    find /var/ -mtime +3 -print
                查找比某个文件新或旧的文件
                    find `pwd` -newer "myfile" ! -new "myfile123" -print
                使用type选项
                    find /etc -type d -print
                    find /etc -type l -print
                使用size选项
                    find ./ -size +1000000c -print    c表示单位是字符、字节
                    find ./ -size +10 -print    没有c表示单位是块
                使用depth选项
                    使用find命令时,可能希望先匹配所有的文件,再在子目录里查找
                    find / -name "CON.FILE" -depth -print
                使用exec或ok来执行shell命令
                    find ./ -type f -exec ls -l{} ;    查找本目录下的所有的普通文件,并逐个对查找出来的这些文件进行ls -l操作
                    find ./ -name "*.log" -mtime +5 -ok rm{} ;    常用于删除一定天数之前的日志文件
                xargs命令
                    在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec。不幸的是,有些系统对能够传递给-exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现一处错误。错误信息通常是“参数列太长”或者“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。-exec会发起多个进程,而xargs不会多个,只用一个,就会减少系统资源的消耗
                        find ./ -perm -7 -print | xargs chmod o-w    xargs的作用是将 find ./ -perm -7 -print 的结果传给 chmod o-w 命令来进行执行
                        find ./ -type f print | xargs file
        5.3.grep介绍(文本过滤)
            简介:
                grep是Unix和Linux中使用最广泛的命令之一
                对文本文件进行模式查找
                对文本进行按行的匹配
                grep有三种变形
                    Grep:标砖grep命令
                    Egrep:扩展grep,支持基本以及扩展的正则表达式
                    Fgrep:快速grep
            grep一般格式:
                grep [选项] 基本正则表达式 [文件]
                其中基本正则表达式最好采用双引号括起来,一是防止被误认为是shell命令,二是可以用来查找多个单词组成的字符串
            grep命令选项
                -c    只输出匹配行的计数
                -i    不区分大小写(只适用于单字符)
                -h    查询多文件时不显示文件名
                -H    查询多文件时显示文件名
                -l    查询多文件时只输出包含匹配字符的文件名
                -n    显示匹配行及行号
                -s    不显示不存在或无匹配文本的错误信息
                -v    显示不包含匹配文本的所有行,功能就是过滤某些文本
            例子
                grep "jenny" *.txt    从所有 txt 文件中查找存在 jenny 的行有哪些
                grep "sort it" *    在所有文件中查找存在 sort it 的行有哪些
                grep -c "2004" myfile    输出 myfile 中有多少行匹配到 2004
                grep -n "2004" myfile    输出 myfile 中匹配 2004 的行及行号
                grep -i "Jul" myfile    输出 myfile 中匹配 Jul 的行,Jul 不区分大小写
                grep -v "2004:22" myfile    过滤掉myfile中含有 2004:22 的行,只输出不含有 2004:22 的行
                grep "2004:22:5[0-9]" myfile    输出 myfile 中含有 2004:22:50 到 2004:22:59 的行
                grep "^[^210]" myfile    输出 myfile 中开头不是 2 也不是 1 也不是 0 的行
                grep "H*P" myfile    输出匹配正则表达式 H*P 模式的行
                grep "[5-8][6-9][0-3]" myfile
                grep "4{2}" myfile
                grep "4{2,}" myfile
                grep "4{2,4}" myfile    输出匹配正则表达式 4{2,4} 模式的行,该模式的含义是 4 连续出现的次数是 2到4 次
                grep "^$" myfile    输出匹配正则表达式 ^$ 模式的行,^$ 的含义是空行
                grep "?" myfile    ? 转义 ?
                grep "^d" lsout.txt        ^d 表示以 d 开头
                grep "^[^d]" lsout.txt        ^[^d] 表示不以d开头
            grep命令类名和等价的正则表达式
                [[:upper:]]        [A-Z]
                [[:alnum:]]        [0-9a-zA-Z]
                [[:lower:]]        [a-z]
                [[:space:]]        空格或tab键
                [[:digit:]]        [0-9]
                [[:alpha:]]        [a-zA-Z]
                例子
                    grep "5[[:digit:]][[:digit:]]" myfile    其中的正则表达式表示 500 到 599 的数字范围
        5.4.awk介绍
            简介:
                可从文件或字符串中基于指定规则浏览和抽取信息
                是一种自解释的编程语言
                三种方式调用awk:
                    命令行方式:awk [-F filed-spearator] 'command' input-files
                    awk脚本:所有awk命令插入一个文件,并令awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它
                    awk命令插入一个单独文件:awk -f awk-script-file input-files
                awk脚本由各种操作和模式组成
                模式和动作:
                    模式部分决定动作语句何时触发及出发事件(BEGIN,END)
                    动作对数据进行处理,放在大括号{}内指明(print)
                分隔符、域和记录
                    awk执行时,其浏览域标记为$1、$2....$n。这种方法称为域标识。$0为所有域
                        例如一行数据 2005 computer is expensive ,默认分隔符是 空格,那么这一行就有4个域,第一个是 2005,第二个是 computer,第三个是 is,第四个是 expensive
                    注意执行时不要混淆符号 $ 和 shell提示符 $ ,它们是不同的
            例子1:
                awk '{print $0}' score.txt | tee score.out        将score.txt文件中的所有信息打印出来,在屏幕上输出信息,并且也将信息输入到score.out文件中
                awk -F : '{print $1" "$4}' score.txt        注意 -F : 作用是将分隔符从默认分隔符 空格 变成 : ,这条命令表示在屏幕上输出 score.txt 文件中以:为分隔符分割后每行中第一个域和第四个域的内容,第一个域和第四个域的内容在输出信息中以 也就是 tab跳隔符分割,在输出域的时候,分隔符:不会输出
                awk 'BEGIN {print "IP Date --------"}{print $1" "$4}END{"end-of-report"}' score.txt    BEGIN {print "IP Date --------"}打印一些报告头,END{"end-of-report"}打印一些报告尾,{print $1" "$4}打印在score.txt中模式匹配的主体信息
            awk特殊字符
                awk中的特殊字符:+、?,+表示匹配任意字符,?表示匹配单个字符
                匹配操作符:~、!~,~表示匹配,!~表示不匹配
            例子2:
                cat score.txt | awk '$0~/218.79.13.196/'    在score.txt中查找出所有匹配 218.79.13.196 的行,注意匹配模式放在//里面
                awk '$1!~/218.79.13.196/' score.txt        在score.txt中,以默认分隔符空格来划分每一行,输出第一个域不匹配(!~)218.79.13.196的行
                awk '{if($1=="218.79.131.96") print $0}' score.txt        在score.txt中,以默认分隔符空格来划分每一行,如果(if)第一个域($1)等于(==)218.79.13.196,就打印这一行的所有信息(也就是这一行的所有域$0)
        5.5.sed介绍
            简介:
                sed不与初始化文件打交道,也就是绝对不会更改原文件的内容,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕
                sed是一个重要的文本过滤工具,使用一行命令或者使用管道与grep与awk相结合
                非交互性文本流编辑
            调用sed的三种方式
                使用sed命令行格式为:sed [选项] sed命令 输入文件
                使用sed脚本文件格式为:sed [选项] -f sed脚本文件 输入文件
                sed脚本文件 [选项] 输入文件
                补充:不管是使用shell命令行方式或是脚本文件方式,如果没有指定输入文件,sed从标准输入中接受输入,一般是键盘或重定向结果
            sed命令选项如下:
                -n    不打印没匹配到的行
                -c    下一命令是编辑命令
                -f    如果正在调用sed脚本文件
            sed在文件中查询文本的方式
                使用行号,可以是一个简单数字,或是一个行号范围
                    x        x为一行好
                    x,y        表示行号范围从x到y
                使用正则表达式
                    /pattern/        查询包含模式的行
                    /pattern/pattern/    查询包含两个模式的行
                    /pattern/,x        在给定行号上查询包含模式的行
                    x,/pattern/        通过行号和模式查询匹配行,从第x行开始一直匹配到有/pattern/的行结束
                    x,y!            查询不包含执行行号x和y的行
            基本sed编辑命令
                p    打印匹配行
                =    显示文件名
                a    在定位行号后附加新文本信息
                i    在定位行号前附加新文本信息
                d    删除定位行
                c    用新文本替换定位文本
                s    使用替换模式替换相应模式
                r    从另一个文件中读文本
                w    写文本到一个文件
                q    第一个模式匹配完成后退出或立即退出
                l    显示与八进制ASCII代码等价的控制字符
                {}    在定位行执行的命令组
                n    从另一个文件中读文本下一行,并附加在下一行
                g    将模式2粘贴到/pattern n/
                y    传送字符
            例子:
                sed '2p' score.txt        基本sed编辑命令p表示打印匹配行,所以这句就是打印第2行,但是没有-n(-n指的是不打印没匹配的行),所以还是会打印所有的行
                sed -n '2p' score.txt        基本sed编辑命令p表示打印匹配行,而且还有-n参数,所以这句就是打印第2行
                sed -n '1,4p' score.txt        基本sed编辑命令p表示打印匹配行,所以 1,4p 表示打印第1到第4行,-n表示不打印不匹配的行
                sed -n '/los/p' myfile.txt        -n表示不打印不匹配的行,所以就是打印匹配 los 字符串的行,以为/los/后有p编辑命令,就是打印匹配行
                sed -n '4,/los/' myfile.txt
                sed -n '/^$/=' myfile
                sed -n -e '/^$/p' -e '/^$=' myfile
                sed -n '/chinaitlab/ashenzhen' myfile.txt
                sed -n '/chinaitlab/ishenzhen' myfile.txt
                sed -n '/chinaitlab/cchinaitlab shenzhen' myfile.txt
                sed '1,2d, myfile.txt        删除1到2行的内容
                sed 's/chinaitlab/chinaitlab shenzhen/g' myfile.txt
                sed -n 's/chinaitlab/& hello/p' myfile.txt        在有chinaitlab的行前面插入 hello
                sed -n 's/chinaitlab/hello &/p' myfile.txt        在有chinaitlab的行后面插入 hello
                sed 'lr ctrl.txt' myfile.txt
                sed '/china/q' myfile.txt
                sed -n '/china/l' myfile.txt
        5.6.合并与分割(sort、uniq、join、cut、paste、split)
            sort [options] files
                许多不同的域按照不同的列顺序排序
                -c    测试文件是否已经分类
                -m    合并两个分类文件
                -u    删除所有复制行
                -o    存储sort结果的输出文件名
                -t    域分隔符;用非空格或tab键分隔域
                +n    n为域名,使用此域名开始分类,sort中的域是从0开始的,不同于awk(awk的域是从1开始的,0表示所有域)
                n    指定分类是域上的数字分类项
                -r    比较逆序
                例子:
                    sort -c myfile        检查myfile有没有排序
                    sort -u myfile        如果myfile有重复的行,就合并这些行为一行
                    sort -r myfile        以逆序排序
                    sort -t "/" +2 myfile        以/作为分隔符,并以第2个域来排序
                    sort -t "/" +2n myfile        以/作为分隔符,并以第2个域按数字排序,+2n中的 n 就是指按数字排序,如果没有n,那么173排在19的后面,因为是逐个比较每个字符,如果有n,就是比较数字173和19的大小来排序
            uniq [options] files
                从一个文本文件中去除或禁止重复行,关于重复的行,统计只对邻近的行有效
                -u    只显示不重复行
                -d    只显示有重复数据行,每种重复行只显示其中一行
                -c    打印每一重复行出现次数
                -f n    n为数字,前n个域被忽略,只比较第n以及第n之后的域,如果某一行域的个数少于n,就不输出该行
                例子:
                    uniq -c myfile.txt        
                    uniq -d myfile.txt
                    uniq -f 2 myfile.txt
                    uniq -d myfile.txt
            join [options] file1 file2
                用来讲来自两个分类文本文件的行连接在一起
                -an        n为数字,用于连接时从文件n中显示不匹配行
                -o n.m     连接域,n为文件名,m为域名
                -j n m    n为文件名,m为域名。使用其他域做连接域
                t        域分隔符,用来设置非空格或tab键的域分隔符
                例子
                    join -a1 -a2 address.txt town
                    join -o 2.2,1.1    address.txt town
                    join -j1 1 -j2 1 address.txt town
            split
                用于将大文件分割成小文件
                命令格式
                    split -output_file-size input-filename output-filename
                    -b n    每个分割文件的大小为n(k,m)
                    -C n    每个分割文件一行最多n个字节数
                    -l n    每个分割文件的行数
                    -n        同-l n
                例子
                    split -10 ls_out.txt split
            cut
                用于从标准输入或文本文件中剪切列或域
            paste
                将按行将不同文件行信息放在一行

  • 相关阅读:
    UVa-129
    UVa-524
    有点迷茫
    北邮之行~
    UVa-253
    心累--期末考试成绩
    UVa-220 Othello
    UVa-201 Squares
    UVA-1589 Xiangqi
    UVa-213 Message Decoding
  • 原文地址:https://www.cnblogs.com/xumenger/p/4293382.html
Copyright © 2020-2023  润新知