2018-6-4第十课笔记

正则表达式介绍-grep(过滤指定关键词)

egrep使用时,不需要添加脱义字符\

概念:它使用单个字符串来描述或匹配一系列符合某个句法则规则的字符串;
正则表示式通常用来检索和替换那些符合某个模式的文本内容。
无论是查找某个文档,还是查询某个日志文件并分析其内容,都会用正则表示式。
正则就是一串有规则的字符串;
掌握好正则对于编写shell脚本有很大帮助;
各种变成语言中都有正则,原理是一样的。
命令格式:grep [-cinvrABC] 'word' filename
常用选项如下:
-c 表示打印符合要求的行数;
-i 表示忽略大小写;
-n 表示输出符合要求的行及其行号;
-v 表示打印不符合要求的号;
-r 遍历所有的子目录
-A 后面跟一个数字,例如-A2表示打印符合要求的行及下面的两行;
-B 后面跟一个数字,例如-B2表示打印符合要求的行及上面的两行;
-C 后面跟一个数字,例如-C2表示打印符合要求的行及上下各两行。
^ 这个符号表示以什么什么开头。如:^# 以#开头;
或者[^#] 取反,除#号开头的行
  • 创建一个grep目录,拷贝过来一个文件/etc/passwd

    [root@localhost /]# mkdir grep #创建一个grep目录
    [root@localhost /]# cd /grep/ #进这个目录里面
    [root@localhost grep]# cp /etc/passwd . #拷贝passwd到.(本目录下)
    [root@localhost grep]# ls #查看目录下有什么文件
    passwd

  • 过滤passwd文件里,nologin的字符

    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)
    这里nologin过滤完后标红,是因为grep有一个--color=auto 添加颜色显示
    可以查看下grep命令
    [root@localhost grep]# which grep #which查看grep
    alias grep='grep --color=auto'
    /usr/bin/grep

  • grep查看符合要求的行数 -c

    [root@localhost grep]# grep -c 'nologin' passwd #-c符合’nologin'的行数
    15

  • grep显示这个文件包包含‘nologin'的行数。

    [root@localhost grep]# grep -n 'nologin' passwd 
    2:bin:x:1:1:bin:/bin:/sbin/nologin
    3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
    4:adm:x:3:4:adm:/var/adm:/sbin/nologin
    5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10:operator:x:11:0:operator:/root:/sbin/nologin
    11:games:x:12:100:games:/usr/games:/sbin/nologin
    12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    13:nobody:x:99:99:Nobody:/:/sbin/nologin
    14:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    15:dbus:x:81:81:System message bus:/:/sbin/nologin
    16:polkitd:x:999:997:User for polkitd:/:/sbin/nologin
    17:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    18:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    19:chrony:x:998:996::/var/lib/chrony:/sbin/nologin

  • grep不区分大小写显示出来 -ni

    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

  • grep取反,除了nologin的显示出来 -v

    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

  • 遍历所有的子目录 -r

    [root@localhost grep]# grep -r 'root' /etc/ (etc目录下所有包含root的文件列出来)
    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

  • -A2把包含root的行,以及这行下面的两行都打印出来。

    [root@localhost grep]# grep -nA2 'root' passwd 
    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

  • -B2把包含root的行,以及这行下面的两行都打印出来。

    [root@localhost grep]# grep -nB2 'root' passwd 
    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

  • -C2把包含root的行以及这上下两行都打印出来。

    [root@localhost grep]# grep -nC2 'root' passwd 
    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

grep正则表达式具体用法示例

查看一个文件里0-9所有的数字,[]括号表示里面的任意一个字符

[root@localhost grep]# grep '[0-9]' passwd 
2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

反选-v,把不包含数字的行列出来。

[root@localhost grep]# grep -nv '[0-9]' /etc/inittab 
2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

取反,过滤掉所有以#开头的行

[root@localhost grep]# grep -nv '^#' inittab
把不是以#开头的行,显示出来

  • 过滤非0-9开头的数字的行显示出来

    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

    过滤出任意一个字符和重复字符,示例如下:

    [root@localhost grep]# grep 'r.o' passwd 
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    2018.4.25 六周第一次课 (正则grep-过滤指定关键词)
    .表示任意一个字符,上例中,r.o表示r与o之间有一个任意字符的行过滤出来。

指定要过滤出的字符出现次数,示例如下:

[root@localhost grep]# grep 'o{2}' passwd 
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
2018.4.25 六周第一次课 (正则grep-过滤指定关键词)
这里用到了符号{}表示内部为数字,表示前面的字符要重复的词数。
{}左右都需要加上转义字符\,另外使用{}还可以表示一个范围,具体格式为{n1,n2}
{}花括号表示前一个字符的范围,如果o{2},表示2个连续的oo显示出来。

过滤出一个或多个指定的字符,示例如下:

[root@localhost grep]# egrep 'o+b' passwd 
nobody:x:99:99:Nobody:/:/sbin/nologin

过滤出零个或一个指定的字符,示例如下:

[root@localhost grep]# egrep 'o?1o' passwd 
bin:x:1o:1:bin:/bin:/sbin/nologin
o1o

过滤出字符串1或者字符串2,示例如下: |或者

[root@localhost grep]# egrep 'root|nologin' passwd 
2018.4.25 六周第一次课 (正则grep-过滤指定关键词)

总结:
. 表示任意一个字符
* 表示*之前零个或者多个字符
{} 表示一个范围
+ 表示匹配一个或多个+前面的字符
? 表示零个或多个任意字符
| 表示或者

sed工具介绍(替换、及替换指定的字符)

sed介绍:sed工具主要是替换的文本输出到屏幕上,而且还有其他更丰富的功能。
sed命令格式:sed -n 'n' p filename,单引号内的n是一个数字,表示几行。
-n选项的作用就是只显示我们要打印的行,无关紧要的内容不显示。

创建一个sed目录,把passwd文件拷贝进来,方便后面学习。
[root@localhost ~]# mkdir sed #创建一个目录
[root@localhost ~]# cd sed/ #进入到目录sed
[root@localhost sed]# cp /etc/passwd test.txt
 #拷贝passwd文件到本目录下,并且修改名字
[root@localhost sed]# ls #查看当前目录下都有哪些文件
test.txt
[root@localhost sed]# pwd #当前所在的位置
/root/sed
只显示我们需要查找的内容显示出来,示例如下:-n
[root@localhost sed]# sed -n '/root/'p test.txt 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
#-n选项是指显示我们要打印的行。

在grep中使用的特殊字符如(^ $ *等) 都可以在sed中使用。

指定一个区间打印, 比如指定一个区域2-3行,示例如下:-n
[root@localhost sed]# sed -n '2,3'p test.txt 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
sed命令加上-e选项可以实现多个行为,示例如下:-e
[root@localhost sed]# sed -e '1'p -e '/bus/'p -n test.txt 
root:x:0:0:root:/root:/bin/bash
dbus:x:81:81:System message bus:/:/sbin/nologin
#sed -e 实现多个行为,如我查找第一行,并且 把文档中含有bus的显示出来
如果需求说查找一个文件,把bus不管大小写都列出来,I
[root@localhost sed]# sed -n '/bus/'Ip test.txt  #这里一定要加一个大I字母。
dbus:x:81:81:System message bus:/:/sbin/nologin
BUS
删除某些行(并非删除),把剩下的行数都显示出来,示例如下:d
[root@localhost sed]# sed '1,18'd test.txt 
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
BUS
#这里后面跟选项d,会把1到18行的内容删除,把后面的内容显示出来。

这里参数d表示删除的东西,它不仅可以删除指定的单行以及多行,而且可以删除匹配某个字符的行,还可以删除从某一行开始到文档最后一行的所有行,这个命令仅仅是在屏幕上并不显示这些行。

sed真正删除选中的行数,示例如下:-i
首先先拷贝一份文件过来:
[root@localhost sed]# cp test.txt test.txt.bak #拷贝过来个备份
[root@localhost sed]# ls #查看当前目录下的文件
test.txt  test.txt.bak
[root@localhost sed]# wc -l test.txt #wc查看一个文件有多少行
20 test.txt
[root@localhost sed]# sed -i '1,18'd test.txt #-i删除1到18行。
[root@localhost sed]# wc -l test.txt #再来看这个文件有多少行。
2 test.txt
-i还可以指定删除某个字符的行,示例如下://
[root@localhost sed]# sed '/root/'d  test.txt
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
BUS
全局指定替换1,10行。 s
[root@localhost sed]# sed '1,10s/root/toor/g' test.txt 
#1,10是范围,后面跟s是替换,/root/替换成/toor/,g表示全局替换。
toor:x:0:0:toor:/toor:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

上述中的参数s就表示替换的动作,参数g表示本行全局替换,如果不加g只会替换本行出现的第一个。

调整两个字符串的位置,示例如下: -r

第一段和最后一段替换位置

[root@localhost sed]# head test.txt | sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:1/'
/bin/bash:x:0:0:root:/root:1
/sbin/nologin:x:1:1:bin:/bin:1
/sbin/nologin:x:2:2:daemon:/sbin:1
/sbin/nologin:x:3:4:adm:/var/adm:1
/sbin/nologin:x:4:7:lp:/var/spool/lpd:1
/bin/sync:x:5:0:sync:/sbin:1
/sbin/shutdown:x:6:0:shutdown:/sbin:1
/sbin/halt:x:7:0:halt:/sbin:1
/sbin/nologin:x:8:12:mail:/var/spool/mail:1
/sbin/nologin:x:11:0:operator:/root:1

小括号在sed中属于特殊符号,必须在前面加转义字符\,替换时则携程类似\1、\2或\3的形式,上列中()把想要替换的字符打包成了一个整体,有这个转义字符\,-r选项让这个表达式更加清晰了。

查看一个文档当中,所有的数字不包含字符。
[root@localhost sed]# head test.txt |sed 's/[a-zA-Z]//g' #这里括号里的是范围
::0:0::/://
::1:1::/://
::2:2::/://
::3:4:://://
::4:7::///://
::5:0::/://
::6:0::/://
::7:0::/://
::8:12::///://
::11:0::/://
如果给文档前面统一添加个字符串,比如aaa,示例如下:
[root@localhost sed]# head test.txt | sed -r 's/(.*)/aaa:&/' #&表示星号前所有
aaa:root:x:0:0:root:/root:/bin/bash
aaa:bin:x:1:1:bin:/bin:/sbin/nologin
aaa:daemon:x:2:2:daemon:/sbin:/sbin/nologin
aaa:adm:x:3:4:adm:/var/adm:/sbin/nologin
aaa:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
aaa:sync:x:5:0:sync:/sbin:/bin/sync
aaa:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
aaa:halt:x:7:0:halt:/sbin:/sbin/halt
aaa:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
aaa:operator:x:11:0:operator:/root:/sbin/nologin

awk工具介绍

awk也是流行的编辑器,针对文档中的行来操作,一行一行的操作;
awk具备sed的所有功能,而且更强大。

awk截取文档中的某个段落,示例如下:

  • -F选项的作用是指定分隔符,如果不加-F选项,以空格或者tab为分隔符。
  • print为打印的动作,用来打印某个字段。$1为第一段,$2为第二段,$0表示整行。
    • 示例1:

      [root@localhost ~]# mkdir awk #创建个awk目录
      [root@localhost ~]# cp /etc/passwd awk/test.txt #拷贝个文件过来并且修改名字
      [root@localhost ~]# cd awk/
      [root@localhost awk]# ls
      test.txt
      [root@localhost awk]# awk -F ':' '{print $1}' test.txt #打印出来第一段,分隔符为冒号“:”
      root
      bin
      daemon
      adm
      lp
      sync
      shutdown
      halt
      mail

    • 示例2,打印出来所有的内容:$0

      [root@localhost awk]# awk '{print $0}' test.txt #$0表示整行,所有。
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon:x:2:2:daemon:/sbin:/sbin/nologin
      adm:x:3:4:adm:/var/adm:/sbin/nologin

匹配字符或者字符串

  • 打印出来包含oo的行。

    [root@localhost awk]# awk '/oo/' test.txt 
    root:x:0:0:root:/root:/bin/bash
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin

  • 打印第一行的第一段包含oo的行。

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

  • 多次打印,多次匹配test,示例如下:

    [root@localhost awk]# awk -F ':' '/root/ {print $1,$3} /bash/ {print $1,$3,$7}' test.txt 
    root 0
    root 0 /bin/bash
    operator 11
    #这命令的意思是 第一和第三段,包含root的字符,和第一段 第三段 第七段包含bash的字符打印出来。

条件操作符

awk中可以用逻辑符号进行判断,比如==就是等于,也可以理解为精确匹配;
另外还有>、>=、<等,在和数字比较时,
若把比较的数字用双引号因起来,那么awk不会认为是数字,
而会认为是字符,不加双引号则会认为是数字。
  • 示例1,精确匹配:

    [root@localhost awk]# awk -F ':' '$3=="0"' test.txt #数字0
    root:x:0:0:root:/root:/bin/bash

  • 示例2,列出来第三段大于等于500的行打印出来

    [root@localhost awk]# awk -F ':' '$3>=500' test.txt 
    polkitd:x:999:997:User for polkitd:/:/sbin/nologin
    chrony:x:998:996::/var/lib/chrony:/sbin/nologin

  • 示例3,!=表示不匹配,第七段不等于/sbin/nologin的有哪些,如下:

    [root@localhost awk]# awk -F ':' '$7!="/sbin/nologin"' test.txt 
    root:x:0:0:root:/root:/bin/bash
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt

  • 可以使用&&和||,他们分别表示并且和或者,用法如下:

    [root@localhost awk]# awk -F ':' '$3<$4' test.txt 
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

  • ||或者的用法如下:

    [root@localhost awk]# awk -F ':' '$3>100 || $7=="/sbin/nologin"' test.txt 
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin

awk的内置变量

awk常用的变量有OFS,NF和NR,OFS和-F选项有类似的功能;
也是用来定义分隔符的,但是它实在输出的时候定义;
NF表示用分割符分割后一共有多少段;
NR表示行号。
  • OFS的用法如下,print打印时的分割符:

[root@localhost awk]# awk -F ':' '{OFS="#"} $3>1000 || $7 ~ /bash/ {print $1,$3,$7}' test.txt 
root#0#/bin/bash
#OFS分隔符,以#号为单位,再写条件$3>1000, 后面在跟print语法。

  • NR表示行,NF表示段,命令介绍如下:

    [root@localhost awk]# awk -F ':' '{print NF":"$0}' test.txt #NF表示列出来有多少段。
    7:root:x:0:0:root:/root:/bin/bash
    7:bin:x:1:1:bin:/bin:/sbin/nologin
    7:daemon:x:2:2:daemon:/sbin:/sbin/nologin
    7:adm:x:3:4:adm:/var/adm:/sbin/nologin
    7:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@localhost awk]# awk -F ':' '{print NR":"$0}' test.txt #NR表示把行号标出来。
1:root:x:0:0:root:/root:/bin/bash
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6:sync:x:5:0:sync:/sbin:/bin/sync

  • 用NR列出前10行

    [root@localhost awk]# awk -F ':' 'NR<=10' test.txt #:表示分割符,NR列行小于10的列出来
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    2018.4.27 六周第三次课 (awk工具)

  • 还可以指定条件匹配一起使用

    [root@localhost awk]# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt 
    #awk -F指定分割符为“:”,NR列出来小于10的行,其中$1第一行 ~包含 /root|或者sync/的列出来。
    root:x:0:0:root:/root:/bin/bash
    sync:x:5:0:sync:/sbin:/bin/sync

awk中的数学运行

  • awk可以更改段值,示例如下,赋值:

    [root@localhost awk]# head -n 3 test.txt |awk -F ':' '$1="root"' =是赋值第一段都赋值成root,列出前三段。
    root x 0 0 root /root /bin/bash
    root x 1 1 bin /bin /sbin/nologin
    root x 2 2 daemon /sbin /sbin/nologin

  • 上例中切割没有分割符,可以OFS定义一下分割符,示例如下:

    [root@localhost awk]# head -n 3 test.txt |awk -F ':' '{OFS=";"} $1="root"' 
    root;x;0;0;root;/root;/bin/bash
    root;x;1;1;bin;/bin;/sbin/nologin
    root;x;2;2;daemon;/sbin;/sbin/nologin

  • awk匹配root的第一行有哪些,示例如下:

    [root@localhost awk]# head -n 3 test.txt |awk -F ':' '$1=="root"' ==是匹配
    root:x:0:0:root:/root:/bin/bash

  • awk计算某个段的总和,示例如下:

    [root@localhost awk]# awk -F ':' '{{tot=tot+$3}}; END {print tot}' test.txt 
    2605

    tot=tot+$3 这段的意思是每一次的值,都会跟第三段相加,实现一个循环,默认是从0开始。 这样可以列出来一个列的总和。

转载于:https://my.oschina.net/u/3851573/blog/1826288

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值