Linux6期 第十二课 正则表达式

回复 收藏
本帖最后由 tangenxin 于 2015-4-15 17:27 编辑

感觉这东西没什么难不难的,多练习就对了。  N多的练习。写的都想吐了

一、grep (-E --color -n -v -c -q -A -B -C -i -r).  *  .*
二、sed    (-n -e  -r -i)
三、awk   ( -F ,NR, NF ,~/root/ ,if)



一、grep
grep  [-civnABC]   'root'  /etc/passwd
--color  添加颜色
-c: 打印符合要求的行数
-i: 忽略大小写
-v: 打印不符合要求的行
-n: 显示行号
-A2: 打印符合的行及下面两行
-B2:     打印符合的行及上面两行
-C2:     打印符合的行及上下两行
-r:     遍历下面所有的文件
-o:     显示出现的次数
-q:     暂不要求
举例:
1、过滤root的行并显示行数
    grep  -n 'root'   /etc/passwd
2、过滤不带root的并显示行数
    grep  -nv 'root' /etc/passwd
3、显示所有包含数字的行
     grep -n '[0-9]'  /etc/passwd
4、有数字的行都不显示
     grep -v '[0-9]' /etc/passwd
5、纯数字的行不显示。如果改行有数字和字母,还是会显示
     grep -n '[^0-9]'   /etc/passwd
6、去除所有root开头的行
     grep -n '^root'   /etc/passwd
7、过滤出所有字母开头的行
     grep -n '^[a-zA-Z]'  /etc/passwd
8、过滤出所有非数字开头的行
     grep -n '^[^0-9]'  /etc/passwd   貌似  grep -nv  '^[^0-9]'  /etc/passwd 一样。 但^[^0-9]可以过滤空号
9、去除所有空号和以#开头的行
     grep -v  '^$' | grep -n '^#'
10、过滤任意一个或多个字符
     grep  'r.o'  1.txt
     grep 'r*t'
     grep 'r.*t'
     .表示任意一个字符     *表示0个或多个前面的字符     .*表示零个或多个任意字符
11、指定过滤字符次数 grep 'o\{2\}' 1.txt

grep   -c -n -v -r  练习
grep  'root'   /etc/passwd
grep -c 'root'  /etc/passwd    统计几行
grep -c ':x:'   /etc/passwd
grep -n  'root' /etc/passwd 显示行号
grep -n -color 'root'  /etc/passwd
grep -n 'root'  /etc/passwd | wc -l   统计root的次数
alias grep='grep --color'
grep -v 'root'  /etc/passwd   不显示root的行
grep -A2 -n 'root'   1.txt     显示下面两行
grep -B2 -n ‘root’/etc/passwd  显示上面两行
grep -C2 -n 'root'  /etc/passwd   显示上下两行
grep -r 'root'   /etc/     遍历含root的行
grep -n '[0-9]' /etc/passwd     显示有数字的行
grep -v -n '[0-9]'  /etc/passwd 显示无数字的行

* .  ? + { }  \
grep  'ro*t'  /etc/passwd
* 命令行里表示零个或多个。 在 grep 里,表示 0个或多个o。即 rt  rot rot root rooot  roooot .....
.  在grep里表示有且仅有一个任意字符
? 在命令行表是任意一个字符。  在grep里,表示0个或1个o。必须与-E 使用
+ 在grep 里表示一个或多个o
.*  任意字符。全匹配


二、egrep
egrep 'o+' 1.txt    表示1个或一个以上前面字符
egrep 'o?'  1.txt    表示0个或一个前面的字符
egrep 'root|bin'  1.txt    显示有root和bin的行。grep -E
egrep 'r(oo)'|bin' 1.txt  匹配roo或者bin的行
egrep '(oo)+' 1.txt  表示1个或多个'oo'

******************************************
直接 echo "alias grep='egrep --color' " >>~/.bashrc  && source ~/.bashrc 得了
******************************************
三、. * + ?
. 表示任意字符
* 表示0或多个前面的字符
+ 表示1或多个前面的字符
?  表示0或1个前面的字符
+ ? 只有egrep支持

四、sed
sed  's///g' 1.txt
-n 取消自动打印模式空间
-r 脱义字符
-r 支持扩展正则表达式
-i 保存
-d 删除
-p 打印

打印和删除
grep -n '.*'  test.txt | sed -n '1,5p'
grep -n '.*'  test.txt | sed -n '/root/p'
grep  '.*'     test.txt | sed -n '/^root/p'
grep  '.*'     test.txt | sed -n '/bash$/p'
grep  '.*'     test.txt | sed '1,10d'
grep  '.*'     test.txt | sed '/root/d'

sed 's/[0-9]//g' test.txt    // 删除所有数字
sed 's/[^0-9]//g' test.txt  // 删除所有非数字
sed 's/root/ROOT/g'  test.txt   -g 所有

sed -i 's/root/ROOT/g'  test.txt  修改root为ROOT并保存

[root@localhost ~]# sed 's/root/ROOT/g'  test.txt
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

1、将 daemon 与/sbin/nologin对调
sed -r 's/(daemon)(.*)(\/sbin\/nologin)/\3\2\1/'
2、将所有小写变大写
sed  's/[a-z]/\u&/g' test.txt  
3、将所有大写变小写
sed 's/[A-Z]/\l&/g' test.txt


sed练习题:
1、把/etc/passwd 复制到/root/test.txt,用sed打印所有行
2、打印test.txt的3到10行
3、打印test.txt 中包含 'root' 的行
4、删除test.txt 的15行以及以后所有行
5、删除test.txt中包含 'bash' 的行
6、替换test.txt 中 'root' 为 'toor'
7、替换test.txt中 '/sbin/nologin' 为 '/bin/login'
8、删除test.txt中5到10行中所有的数字
9、删除test.txt 中所有特殊字符(除了数字以及大小写字母)
10、把test.txt中第一个单词和最后一个单词调换位置
11、把test.txt中出现的第一个数字和最后一个单词替换位置
12、把test.txt 中第一个数字移动到行末尾
13、在test.txt 20行到末行最前面加 'aaa:'    sed '20,$s/.*/aaa:&/g'

1、cat /etc/passwd | tee test.txt  | sed -n '1,$p'
2、grep -n '.*'  test.txt |sed -n '3,10p'
3、grep -n '.*'  test.txt | sed -n '/root/p'
4、grep -n '.*'  test.txt | sed  '15,$d'
5、grep -n '.*'  test.txt | sed 's/root/toor/g'   -g  全部替换
6、grep -n '.*'  test.txt | sed 's/
7、grep -n '.*' test.txt | sed -r 's@\/sbin\/nologin@\/bin\/login@'
8、grep -n '.*' test.txt | sed -r '5,10s/[0-9]//g'
9、grep -n '.*' test.txt | sed -r 's/[^0-9a-zA-Z]//g'
10.  sed 's/\(^[a-zA-Z][a-zA-Z]*\)\([^a-zA-Z].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)/\4\2\3\1/' test.txt
11.  sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)#\1\5\3\4\2#' test.txt
12.  sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*$\)#\1\3\2#' test.txt
13.  sed 's/^.*$/&aaa/'  test.txt    //  sed '1,10s/^.*/aaa:&/'  test.txt   在每行前加入aaa:

三.  awk
1、截取第三断字符
[root@localhost ~]# awk -F :  '{print $3}' test.txt | tail -1
74
[root@localhost ~]# awk -F :  '{print $1"@"$3}' test.txt  | head -1
root@0
[root@localhost ~]# awk -F  :  '{print $1$3}' test.txt | tail -1
sshd74
[root@localhost ~]# awk -F  :  '{print $1,$3}' test.txt | tail -1
sshd 74
[root@localhost ~]# awk -F  : 'OFS="#" {print $1,$3}' test.txt | tail -1   OFS="#"   以#为分隔符
sshd#74
[root@localhost ~]# awk '/root/' test.txt | tail -1      过滤 root 字符
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk -F : '/root/ {print $3}' test.txt  | tail -1      过滤root行并只打印第三列
11
[root@localhost ~]# awk -F : ' /root/ OFS=":" {print NR,$3}'  test.txt     OFS 不可以哦
awk:  /root/ OFS=":" {print NR,$3}
awk:            ^ syntax error
[root@localhost ~]# awk -F : ' /root/  {print NR":"$3}'  test.txt  
1:0
11:11
[root@localhost ~]# awk -F : 'NR":"NF' test.txt  | tail -1               不加{print } 命令貌似无效
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost ~]# awk -F : '{print NR":"NF}' test.txt  | tail -1    // NR代表行,NF代表有多少段
20:7
[root@localhost ~]# awk '/ro?t/'  test.txt   | tail -1
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
[root@localhost ~]# awk '/ro+t/' test.txt | tail -1   
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk '/r(oo)+t/' test.txt | tail -1
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk '/root|sbin/' test.txt  | tail -1
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

[root@localhost ~]# awk -F : '$1=="root" {print $0}' test.txt   (< , > , >= , <= , ==)
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk -F : '$1=="root"' test.txt            
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk -F : '$1==root' test.txt     root必须加""

[root@localhost ~]# awk -F : '$1~/root/' test.txt      ~ 模糊匹配
root:x:0:0:root:/root:/bin/bash

[root@localhost ~]# awk -F: 'OSF=":" $7=$3+$4 {print $0}' test.txt | tail -1
awk: OSF=":" $7=$3+$4 {print $0}
awk:           ^ syntax error
[root@localhost ~]# awk -F: 'OFS=":" , $7=$3+$4 {print $0}' test.txt | tail -1      OFS="vlaue"后必须加逗号
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:148

[root@localhost ~]# awk -F : '$1=="root" || $3=="1" {print $0}' test.txt     
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
打印5~10行
[root@localhost ~]# awk -F : 'NR>=5 && NR<=10 {print NR":"$0}' test.txt   
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

计算第三段的总和
[root@localhost ~]# awk -F: '{(sum=sum+$3)};END {print sum}' test.txt     // END必须大写哦
1007
[root@localhost ~]# sum=0; for i in `awk -F: '{print $3}' test.txt`;do let sum=$sum+$i ;done;echo $sum ;unset sum            
1007      // let sum=$sum+$i  ,+号之间不能有空格

if条件
[root@localhost ~]# awk -F: '$1=="root" {print $0}' test.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk -F: '{if ($1=="root") print $0}' test.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
2015-04-15 17:23 举报
已邀请:

回复帖子,请先登录注册

退出全屏模式 全屏模式 回复
评分
可选评分理由: