[9] 正则表达式

来源:互联网 发布:软件测试技术大全 pdf 编辑:程序博客网 时间:2024/05/20 17:59

[9] 正则表达式

正则表达式,又称规则表达式。(英语:Regular Expression,正则就是一串有规律的字符串。正则表通常被用来检索、替换那些符合某个模式(规则)的文本。

9.1 grep 命令详解

  • 基本语法和参数
语法: grep [-cinvABC] '过滤关键词' 文件名-c :打印符合要求的行数  只显示符合关键词的总行数,不显示行的内容-n :在输出符合要求的行的同时连同行号一起输出-i :不区分搜索大小写-v :打印不符合要求的行 -r : 会把目录下面所有的文件全部遍历,不加r,只能针对文件搜索,而不是整个目录下的文件内容。遍历文件,同时也会把匹配到的关键字所在的文件路径列出来,如果不想列出文件路径,使用-h参数就可以了-A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行 -B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行 -C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行--color: 把匹配到的关键词用红色标识  永久显示,把设置别名的命令写到.bashrc文件中,source .bashrc生效环境变量. 表示任意一个字符; * 表示零个或多个(任意个)前面的字符; .* 表示零个或多个任意字符,空行也包含在内
  • grep/egrep示例

过滤出带有某个关键词的行并输出行号

[root@localhost ~]# grep -n 'root' 1.txt 

过滤出不带有某个关键词的行并输出行号

[root@localhost ~]# grep -n -v 'root' 1.txt 

过滤出所有包含数字的行

[root@localhost ~]# grep '[0-9]' 1.txt

过滤出所有不包含数字的行

[root@localhost ~]# grep -v '[0-9]' 1.txt 

过滤出包含root的行以及下面一行

[root@localhost ~]# grep -A1 'root' 1.txt

过滤出包含root的行以及上面一行

[root@localhost ~]# grep -B1 'root' 1.txt

过滤出包含root的行以及上下各一行

[root@localhost ~]# grep -C1 'root' 1.txt

去除所有以’#’开头的行

[root@localhost ~]# grep -v '^#' 1.txt [root@localhost ~]# grep  '^[#]' 1.txt

去除所有空行和以#开头的行

[root@localhost ~]# grep -v '^$' 1.txt|grep -v '^#' 

过滤出以英文字母开头的行

[root@localhost ~]# grep '^[a-zA-Z]' 1.txt

过滤出以非数字开头的行

[root@localhost ~]# grep '^[^0-9]' 1.txt 说明: 在[]里面加^表示取非grep '^[^0-9]' 1.txt  过滤出非数字开头的行,不包括数字、空行,包括特殊字符,字母,空格 grep -v '^[0-9]' 1.txt 过滤出非数字开头的行,不包括数字,包括空行、特殊字符、字母、空格

过滤任意一个或多个字符

[root@localhost ~]# grep 'r.o' 1.txt[root@localhost ~]# grep 'r*t' 1.txt[root@localhost ~]# grep 'r.*t' 1.txt

指定过滤字符次数

[root@localhost ~]# grep 'o\{2\}' 1.txtgrep 'o\{2\}' 1.txt == grep -E '(oo)' 1.txt

把一个目录下,过滤所有*.php文档中含有eval的行

[root@localhost ~]# grep -r --include="*.php" 'eval' /data/
  • egrep 命令详解

    egrep执行效果与”grep-E”相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。


指定过滤字符次数
[root@localhost ~]# egrep 'o{2}' 1.txt

匹配1个或1个以上+前面的字符

[root@localhost ~]# egrep 'o+' 1.txt

匹配0个或者1个?前面字符

[root@localhost ~]# egrep 'oo?' 1.txt

匹配roo或者nologin

[root@localhost ~]# egrep 'roo|nologin' 1.txt

匹配1个或者多个 ‘oo’

[root@localhost ~]# egrep '(oo)+' 1.txt[root@localhost ~]# egrep '(oo){2}' 1.txt

用括号表示一个整体,下面例子会匹配roo或者ato

[root@localhost ~]# egrep 'r(oo)|(at)o' 1.txt 

9.2 sed 命令详解

sed 可以过滤、替换、删除、调换

-r                        对特殊字符进行脱意,等同于使用\-n                         只打印符合规范的行/关键字/p                   搜索打印关键字行/关键字/d                   搜索删除关键字行s/关键字/替换内容/g         文本替换
  • sed 示例

打印指定行

[root@localhost ~]# sed '10'p -n 1.txt [root@localhost ~]# sed '1,4'p -n 1.txt [root@localhost ~]# sed '5,$'p -n 1.txt说明: 这里的p是print的意思,加上-n后就可以只打印符合规则的行,如果不加则会把1.txt从头到尾打印一遍。

打印包含某个字符串的行

[root@localhost ~]# sed -n '/root/'p 1.txt 可以使用 ^ . * $等特殊符号 [root@localhost ~]# sed -n '/ro.t/'p 1.txt [root@localhost ~]# sed -n '/^roo/'p 1.txtsed跟grep一样,不识别+|{}()等符号,需要借助脱义符号\或者使用选项-r [root@localhost ~]# sed -nr '/ro+/'p 1.txt [root@localhost ~]# sed -n '/ro\+/'p 1.txt 上面两个命令效果是一样的。

-e 可以实现同时进行多个任务

[root@localhost ~]# sed -e '/root/p' -e '/body/p' -n 1.txt 也可以用;实现 [root@localhost ~]# sed '/root/p; /body/p' -n 1.txt

删除指定行

[root@localhost ~]# sed '/root/d' 1.txtsed '1d' 1.txt          删除第一行sed '1,10d' 1.txt       删除110行说明:'/root/d' 删除包含root的行

删除所有数字

[root@localhost ~]# sed 's/[0-9]//g' 1.txt 说明: 其实就是把所有数字替换为空字符,g的作用是替换一行中出现的所有字符

文本替换

[root@localhost ~]# sed '1,12s/root/toor/g' 1.txt[root@localhost ~]# sed -r '1,12s/ro+/toor/g' 1.txt

删除所有非数字

[root@localhost ~]# sed 's/[^0-9]//g' 1.txt

调换两个字符串位置

[root@localhost ~]# head -n2 1.txt |sed -r 's/(root)(.*)(bash)/\3\2\1/' 说明:在sed中可以用()去表示一个整体,本例中把root和bash调换位置,后面的\1\2\3分别表示第一个小括号里面的,第二个小括号里面的以及第三个小括号里面的内容。

-i 选项可以直接修改文件内容

[root@localhost ~]# sed -i 's/ot/to/g' 1.txt

I参数匹配关键词时不区分大小写

[root@localhost ~]# sed -n '/root/'Ip 1.txtgrep使用-i选项不区分大小写

9.3 awk 命令详解

可以截取、过滤、数学计算

  • awk示例

截取文档中的某段

[root@localhost ~]# awk -F ':' '{print $1}' 1.txt ==cut -d: -f1 1.txt说明: -F指定分隔符号为:,若要截取所有的段,使用$0也可以使用自定义字符连接每个段 [root@localhost ~]# awk -F':' '{print $1"#"$2"#"$3"#"$4}' 1.txt 或者使用awk内部变量OFS,格式如下: # awk -F ':' '{OFS="#"} {print $1,$2,$3,$4}' 1.txt

匹配字符或字符串

[root@localhost ~]# awk '/oo/' 1.txt 

针对某个段匹配

[root@localhost ~]# awk -F ':' '$1 ~/oo/' 1.txt 

多次匹配

[root@localhost ~]# awk -F ':' '/root/ {print $1,$3}; $1 ~/test/; $3 ~/20/' 1.txt

条件操作符[==]、[>]、[<]、[!=]、[>=]、[<=]

第三段为0 [root@localhost ~]# awk -F ':' '$3=="0"' 1.txt第三段大于等于500 [root@localhost ~]# awk -F ':' '$3>=500' 1.txt说明:当比较数字时,不能加双引号,如果写成$3>="500"就不符合我们的需求了。第七段不是'/sbin/nologin' [root@localhost ~]# awk -F ':' '$7!="/sbin/nologin"' 1.txt第三段小于第四段 [root@localhost ~]# awk -F ':' '$3<$4' 1.txt ;第三段大于5,并且第三段小于7 [root@localhost ~]# awk -F ':' '$3>5 && $3<7' 1.txt第三段大于5或者第七段为'/bin/bash' [root@localhost ~]# awk -F ':' '$3>"5" || $7=="/bin/bash"' 1.txt

awk内置变量 NF(段数fields) NR(行数records)

[root@localhost ~]# head -n3 1.txt | awk -F ':' '{print NF}' [root@localhost ~]# head -n3 1.txt | awk -F ':' '{print $NF}' 打印最后一段[root@localhost ~]# head -n3 1.txt | awk -F ':' '{print NR}'awk -F ':' '{print NF "#" NR}' passwd打印20行以后的行 [root@localhost ~]# awk 'NR>20' 1.txt 打印20行以后并且第一段包含'ssh'的行 [root@localhost ~]# awk -F ':' 'NR>20 && $1 ~ /ssh/' 1.txt 更改某个段的值 [root@localhost ~]# awk -F ':' '$1="root"' 1.txt

数学计算, 把第三段和第四段值相加,并赋予第七段

[root@localhost ~]# awk -F ':' '{$7=$3+$4; print $0}' 1.txt 但是这样的话,相当于改变了原来文本的结构,所以print $0的时候就不再有分隔符显示。如果想显示分隔符需要借助OFS [root@localhost ~]# awk -F ':' '{OFS=":"} {$7=$3+$4; print $0}' 1.txt

计算第三段的总和

[root@localhost ~]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' 1.txt 

awk中也可以使用if关键词

[root@localhost ~]# awk -F ':' '{if ($1=="root") print $0}' 1.txt[root@localhost ~]# awk -F ':' '{if ($1~/root/) print $0}'   $0代表整行

扩展

  • 打印文件中特定的某行到某行之间的内容
[root@localhost ~]# sed -n '/ens33/,/TX/p' 1.txt ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500        inet 192.168.1.11  netmask 255.255.255.0  broadcast 192.168.1.255        inet6 fe80::e573:6122:85e7:b1a9  prefixlen 64  scopeid 0x20<link>        ether 00:0c:29:a0:8e:5c  txqueuelen 1000  (Ethernet)        RX packets 716  bytes 68017 (66.4 KiB)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 570  bytes 65787 (64.2 KiB)


  • sed 如何转换大小写字母

sed中,使用\u表示大写,\l表示小写

1. 把每个单词的第一个小写字母变大写:sed 's/\b[a-z]/\u&/g' filename2. 把所有小写变大写:sed 's/[a-z]/\u&/g' filename3. 大写变小写:sed 's/[A-Z]/\l&/g' filename
  • sed在文件中某一行最后添加一个数字
[root@localhost ~]# sed  -n "s/\(^a.*\)/\1 123/p" passwd adm:x:3:4:adm:/var/adm:/sbin/nologin 123abrt:x:173:173::/etc/abrt:/sbin/nologin 123
  • sed删除某关键字的下一行到最后一行
[root@test200 ~]# cat testabcdef[root@test200 ~]# sed '/c/{p;:a;N;$!ba;d}' testabc定义一个标签a,匹配c,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。if 匹配"c":a追加下一行if 不匹配"$"goto a最后退出循环,d命令删除
  • 如何使用sed打印1到100行包含某个字符串的行
[root@localhost ~]# sed  -n '1,100{/abc/p}'  1.txt
  • awk 中使用外部shell变量
A=44echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。有多少个变量需要赋值,就需要多少个-v选项。与之等价的:应用于脚本中:#! /bin/bashsort -n filename |awk -F ':' '{print $1}'|uniq >id.txtfor id in `cat id.txt`; do        echo "[$id]"        awk -v id2=$id -F ':' '$1==id2 {print $2}' filename  // 另外的方式为: awk -F ':' '$1=="'id'" {print $2}' filename  done附件:cat filename1111111:134432534562222222:132112221221111111:136435435443333333:123412431232222222:12123123123运行脚本后结果为:[1111111]1344325345613643543544[2222222]1321122212212123123123[3333333]12341243123
  • awk 合并一个文件
把两个文件中,第一列相同的行合并到同一行中awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}'  1.txt  2.txt解释:NR表示读取的行数,FNR表示读取的当前行数所以其实NR==FNR 就表示读取2.txt的时候。 同理NR>FNR表示读取1.txt的时候数组a其实就相当于一个map
  • 把一个文件多行连接成一行
a=`cat file`;echo $a awk '{printf("%s ",$0)}' file   // %s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有cat file |xargs
  • awk中gsub函数的使用
passwd文件中把所有www替换为abcawk 'gsub(/www/,"abc")' /etc/passwd替换$1中的www为abcawk -F ':' 'gsub(/www/,"abc",$1) {print $0}' /etc/passwd
  • awk 截取指定多个域为一行
for j in `seq 0 20`; do        let x=100*$j        let y=$x+1        let z=$x+100        for i in `seq $y $z` ; do                awk  -v a=$i '{printf $a " "}' example.txt >>/tmp/test.txt                echo " " >>/tmp/test.txt        donedone
  • 过滤两个或多个关键词
找出文件(filename)中包含123或者包含abc的行grep -E '123|abc' filename用egrep同样可以实现egrep '123|abc' filename awk 的实现方式awk '/123|abc/'  filename
  • 用awk生成以下结构文件
用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS)  各列的值应如下所示,每增加一行便加1,共500万行。1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,20051001101012,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101#! /bin/bashfor i in `seq 1 5000000`; do    n=`echo "$i"|awk '{print length($0)}'`    export m=$[10-$n]    export o=`perl -e '$a='0'; $b=$a x $ENV{"m"}; print $b;'`    export j=$i    p=`perl -e '$c=$ENV{"o"}.$ENV{"j"}; print $c;'`    echo "$i,$i,$p,$p,$p,$p,$p,$p,`date +%Y%m%d%H%M%S`"doneawk 实现方式awk 'BEGIN{for(i=1;i<=10;i++)printf("%d,%d,%010d,%010d,%010d,%010d,%010d,%010d,%d\n",i,i,i,i,i,i,i,i,strftime("%Y%m%d%H%M"))}'
  • awk用print打印单引号
awk '{print "This is a '"'"'"$1} filename 解释一下:在awk中使用脱义字符\是起不到作用的,如果想打印特殊字符,只能使用'""' 这样的组合才可以。这里自左至右为单引号 双引号 双引号 单引号其中两个单引号为一对,两个双引号为一对。想脱义$那就是'"$"' 脱义单引号那就是 '"'"'
  • 合并两个文件
paste  filename1  filename2 -d 指定连接符paste -d '+'  a.txt b.txt
  • awk的参考教程
原创粉丝点击