专栏首页linux运维学习linux学习第二十六篇:正则介绍,grep,sed,awk命令

linux学习第二十六篇:正则介绍,grep,sed,awk命令

正则介绍

正则就是一串有规律的字符串,掌握好正则对于编写shell脚本有很大帮助,各种编程语言中都有正则,原理是一样的。正则表达式是这样解释的:它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找某个文档,抑或查询某个日志文件分析其内容,都会用到正则表达式。其实正则表达式,只是一种思想,一种表示方法。只要我们使用的工具支持表示这种思想那么这个工具就可以处理正则表达式的字符串。常用的工具有grep, sed, awk 等

grep命令

语法: grep [-cinvABC] ‘word’ filename -c :打印符合要求的行数 -i :忽略大小写 -n :在输出符合要求的行的同时连同行号一起输出 -v :取反,打印出没有你输入的word的行 -r :遍历所有子目录查询你要查的word -A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行 -B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行 -C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行

PS:在正则表达式中, “^” 表示行的开始, “$” 表示行的结尾,那么空行则可以用 “^$” 表示

[root@xie-02 grep]# grep -n 'root' /etc/passwd //在输出符合要求的行的同时连同行号一起输出
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

[root@xie-02 grep]# grep -nv 'nologin' /etc/passwd //打印出没有nologin的行并显示行号
1:root:x:0:0:root:/root:/bin/bash
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

[root@xie-02 grep]# grep '[0-9]' passwd //打印出含有0-9中任意数字的行
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

[root@xie-02 grep]# grep -vn '^#' inittab //把不以#号开头的行打印出来
14:defwerfgdsgf
[root@xie-02 grep]# grep -v '^#' inittab |grep -v '^$' //去除所有空行和以 ‘#’ 开头的行
defwerfgdsgf

[root@xie-02 grep]# grep '[^a-zA-Z]' 1.txt //打印出含有除a-zA-Z之外的字符(也就是一整行都是字符的不会显示)
123
4335
4576
asff564
#qqefe
#123123

[root@xie-02 grep]# grep '^[^a-zA-Z]' 1.txt //打印出不以大小写字符开头的行
123
4335
4576
#qqefe
#123123

[root@xie-02 grep]# grep 'r.o' passwd //. 表示任意一个字符,就是把符合r与o之间有一个任意字符的行打印出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@xie-02 grep]# grep 'ooo*' passwd  //‘ooo*’ 表示oo, ooo, oooo ... 或者更多的 ‘o’
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

[root@xie-02 grep]# grep '.*' passwd  //打印出所有。‘.*’代表任意个任意字符
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
...
..
.(篇幅太多,省略)

[root@xie-02 grep]# grep 'o\{2\}' passwd //在正则当中{}表示范围,o{2}表示连续出现2次o,但是直接写{}不会识别,所以需要脱义字符\
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

[root@xie-02 grep]# grep -E 'o{2}' passwd //加上参数-E就不需要脱义字符
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

[root@xie-02 grep]# egrep 'o{2}' passwd //egrep不需要脱义字符
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

[root@xie-02 grep]# grep -E '(oo){2}' passwd //()表示oo是一个整体,()也需要脱义
chrooooony:x:997:995::/var/lib/chrony:/sbin/nologin

[root@xie-02 grep]# grep 'o\+o' /etc/passwd // ‘+’表示一个或多个o,‘*’表示0个或多个。
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

[root@xie-02 grep]# grep 'o\?2' passwd //?表示零个或1个o
daemon:x:2:2:daemon:/sbin:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin

[root@xie-02 grep]# grep -E 'root|nologin' passwd //‘|’表示或者,打印出有root的行或者有nologin的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...
..
.(篇幅太多,省略)
  1. 不管是‘ + ’‘?’还是‘ * ’当前面有字符时都与前面的字符有关,如o*,o?或者o+都是计算o的个数。 ‘+’表示一个或多个o ‘ * ’表示0个或多个 ‘?’表示零个或1个o
  2. 当使用grep需要脱义时,使用egrep就不需要脱义。
  3. { }花括号表示范围,表示前面的字符的范围,如o{2}表示连续出现2次o
  4. ‘ | ’表示或者的意思

扩展 把一个目录下,过滤出所有*.php文档中含有eval的行 grep -r –include=”*.php” ‘eval’ /data/

sed命令

grep工具的功能其实还不够强大,grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。以前用vim的时候,可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。sed工具以及下面要讲的awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。

命令:sed -n:打印出处理后的行

-r:加上-r参数就可以不加脱义字符

-e:可以实现多个行为

-i:可以对文件内容真正的修改,而不止是把处理后的结果显示屏幕上而没真正修改文件内容

-n:打印包含某个字符的行

[root@xie-02 sed]# sed -n '/root/'p test.txt //打印含有root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@xie-02 sed]# sed -n '/o\+t/'p test.txt //特殊符号要脱义,方式与grep差不多
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@xie-02 sed]# sed -nr '/o+t/'p test.txt //不加脱义字符就加参数-r
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@xie-02 sed]# sed -n '/^c/'p test.txt //打印以 c 开头的行
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
chrooooony:x:997:995::/var/lib/chrony:/sbin/nologin

[root@xie-02 sed]# sed -n /t$/p test.txt //打印以 t 结尾的行
halt:x:7:0:halt:/sbin:/sbin/halt

PS:不加脱义字符就加参数-r

I:不区别大小写

[root@xie-02 sed]# sed -n '/bus/'Ip test.txt /
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
BUS::::324252523

打印指定的行

[root@xie-02 sed]# sed -n '2'p test.txt //打印第二行
bin:x:1:1:bin:/bin:/sbin/nologin

[root@xie-02 sed]# sed -n '2,5'p test.txt //打印第2到第5行
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

[root@xie-02 sed]# sed -n '19,$'p test.txt //打印第19行到最后一行
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
chrooooony:x:997:995::/var/lib/chrony:/sbin/nologin

[root@xie-02 sed]#  sed -n '1,$'p 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
adm:x:3:4:adm:/var/adm:/sbin/nologin
...
..
.(篇幅太多,省略)

-e:可以实现多个行为

[root@xie-02 sed]# sed -e '1'p -e '/bus/'p -n test.txt //打印第一行并且打印包含有bus的行
root:x:0:0:root:/root:/bin/bash
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin

[root@xie-02 sed]# sed -e '1'p -e '/root/'p -n test.txt //如果有多个行为之间有相同结果,都会打印出来
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

d:删除指定的行或包含指定信息的行

[root@xie-02 sed]# sed '1,19'd test.txt  //删除第1到第19行,屏幕显示的是删除之后剩下的。但是不是真正去删除你的文件内容
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
chrooooony:x:997:995::/var/lib/chrony:/sbin/nologin
BUS::::324252523

[root@xie-02 sed]# wc -l test.txt 
23 test.txt
[root@xie-02 sed]# sed -i '1,19'd test.txt //加上-i参数就会真正删除你的文件内容
[root@xie-02 sed]# wc -l test.txt 
4 test.txt

[root@xie-02 sed]# sed -i '/ch/'d test.txt //删除包含有ch的行
[root@xie-02 sed]# cat test.txt 
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
BUS::::324252523

s:替换字符或字符串,g:全局替换

[root@xie-02 sed]# sed '1,5s/root/toor/g' test.txt //在第1到第5行中把root替换为toor
toor:x:0:0:toor:/toor:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
..
.(篇幅太多,省略)

[root@xie-02 sed]# head 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
[root@xie-02 sed]# head test.txt | sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' //把第一段和最后一段交换,
//第一个括号里([^:]+)的表示一个或多个非‘:’的字符,这里代表了root字符,‘:’代表第一个分号,
//(.*)表示第一个分号后的任意个任意字符直到最后一个分号,也就表达式里括号外的第二个分号,
//([^:]+)表示最后一个分号后一个或多个非‘:’字符。1,2,3分别表示前面对应的第一个第二个第三个括号。
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon

[root@xie-02 sed]# sed 's/[a-zA-Z]//g' test.txt //把所有的英文字母都删除
::0:0::/://
::1:1::/://
::2:2::/://
...
..
.(篇幅太多,省略)

[root@xie-02 sed]# head test.txt | sed -r 's/(.*)/aaa:\1/' //在前面添加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
[root@xie-02 sed]# head test.txt | sed -r 's/(.*)/aaa:&/' //在前面添加aaa:,
//\1也可以用&表示,代表前面的括号里的内容
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

PS:‘s’ 就是替换的命令, ‘g’ 为本行中全局替换,如果不加 ‘g’ 只换该行中出现的第一个。除了可以使用 ‘/’ 作为分隔符外,还可以使用其他特殊字符例如 ‘#’ 或者 ‘@’ 都没有问题。 sed不会更改文件内容,加了参数 -i 才会更改

sed练习题,使用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:’

awk命令

上面也提到了awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk支持分段。

PS:awk不需要脱义字符,默认是支持的。

截取文档中的某个段,-F:指定输入分隔符

[root@xie-02 awk]# awk -F ':' '{print $1}' test.txt //截取以:分割的第一段(不会更改文件内容)
root
bin
daemon
...
..
.(篇幅太多,省略)

[root@xie-02 awk]# head -n2 test.txt|awk -F ':' '{print $0}' //打印所有的段。-F ‘:’可不加。
//如果awk没有指定分隔符,会默认以空格,空白字符为分隔符去打印
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@xie-02 awk]# head -n2 test.txt|awk -F':' '{print $1,$2}' //打印第一段第二段,用逗号分隔
root x
bin x

[root@xie-02 awk]# head -n2 test.txt |awk -F ':' '{print $1"#"$2"#"$3"#"$4}'//print还可以打印自定义的内容,
//但是自定义的内容要用双引号括起来。
root#x#0#0
bin#x#1#1

$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。

匹配字符或字符串

[root@xie-02 awk]# awk '/oo/' test.txt //匹配出有oo的行
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

[root@xie-02 awk]# awk -F ':' '$1 ~/oo/' test.txt //匹配出第一段有oo的行。这里的’~’就是匹配的意思。
root:x:0:0:root:/root:/bin/bash

[root@xie-02 awk]# awk -F ':' '/root/ {print $1,$3} /sshd/ {print $1,$3}' test.txt //匹配出含有root的行的第一段和第三段字符,
//以及匹配出含有sshd的行的第一段和第三段字符。
root 0
operator 11
sshd 74
[root@xie-02 awk]# awk -F ':' '/root|sshd/ {print $1,$3}' test.txt  //匹配出含有root或者sshd的行的第一段和第三段字符,同上。
root 0
operator 11
sshd 74

条件操作符

[root@xie-02 awk]# awk -F ':' '$3==0' test.txt //匹配出第三段等于0的
root:x:0:0:root:/root:/bin/bash

[root@xie-02 awk]# awk -F ':' '$3==0 {print $1}' test.txt //匹配出第三段等于0的并输出第一段字符
root

[root@xie-02 awk]# awk -F ':' '$7!="/sbin/nologin"' test.txt //匹配出第七段不是/sbin/nologin的
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@xie-02 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

[root@xie-02 awk]# awk -F ':' '$3>"5" && $3<"7"' test.txt //匹配第三段大于字符5,并且第三段小于字符7
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
tss:x:59:59:Account used by the trousers package

[root@xie-02 awk]# awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt //匹配出第三段大于1000,或者第七段为/bin/bash
root:x:0:0:root:/root:/bin/bash

awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, >=, <, <=, != 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。

awk内置的变量

NF :用分隔符分隔后一共有多少段 NR :行数

[root@xie-02 awk]# awk -F ':' '{OFS="#"} {print $1,$2}' test.txt //匹配出第一段和第二段,并把分隔符分割的换成#号
root#x
bin#x
daemon#x

[root@xie-02 awk]# awk -F ':' '{OFS="#"} $3>100 {print $1,$2}' test.txt //匹配出第三段大于100并输出第一段和第二段,
并把分隔符分割的换成#号也可以表示成  awk -F ':' '{OFS="#"} {if($3>100) {print $1,$2}}' test.txt 
systemd-bus-proxy#x
systemd-network#x
polkitd#x
chrony#x

[root@xie-02 awk]# head -n3 test.txt | awk -F ':' '{print NR ":" ,$0}' //显示行号
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

[root@xie-02 awk]# head -n3 test.txt | awk -F ':' '{print NF ":" $0}' //显示每一行有多少段
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

[root@xie-02 awk]# awk -F ':' 'NR<=3' 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

[root@xie-02 awk]# awk -F ':' 'NR<=3 && $1 ~ /root|bin/' test.txt //在前三行中匹配有包含root或bin的字符的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@xie-02 awk]# awk -F ':' 'NF==6 && $1 ~ /root|bin/' test.txt //匹配出只有六段并且包含root或bin的字符的行
bin:x:1:1:bin:/bin

[root@xie-02 awk]# awk -F ':' '{print $NR ":" $NF}' test.txt //NR表示行号,
//$NR表示第一行就是$1,第二行就是$2依次类推,
//第一行就取第一段,第二行就取第二段.....。$NF就是最后一段的值
root:/bin/bash
x:/bin
2:/sbin/nologin
4:/sbin/nologin
...
..
.(篇幅太多,省略)

[root@xie-02 awk]# head -n3 test.txt | awk -F ':' '$1="root"' //把第一段的都赋值为root
root x 0 0 root /root /bin/bash
root x 1 1 bin /bin
root x 2 2 daemon /sbin /sbin/nologin
[root@xie-02 awk]# head -n3 test.txt | awk -F ':' '{OFS=":"} $1="root"' //把第一段的都赋值为root,
//并且在分隔的地方都加上分号
root:x:0:0:root:/root:/bin/bash
root:x:1:1:bin:/bin
root:x:2:2:daemon:/sbin:/sbin/nologin

[root@xie-02 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt //把每一行的第三段求和
3661

这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法

awk练习题,使用awk命令实现:

  1. 用awk 打印整个test.txt (以下操作都是用awk工具实现,针对test.txt)
  1. 查找所有包含 ‘bash’ 的行
  1. 用 ‘:’ 作为分隔符,查找第三段等于0的行
  1. 用 ‘:’ 作为分隔符,查找第一段为 ‘root’ 的行,并把该段的 ‘root’ 换成 ‘toor’ (可以连同sed一起使用)
  1. 用 ‘:’ 作为分隔符,打印最后一段
  1. 打印行数大于20的所有行
  1. 用 ‘:’ 作为分隔符,打印所有第三段小于第四段的行
  1. 用 ‘:’ 作为分隔符,打印第一段以及最后一段,并且中间用 ‘@’ 连接 (例如,第一行应该是这样的形式 ‘root@/bin/bash‘ )
  1. 用 ‘:’ 作为分隔符,把整个文档的第四段相加,求和

扩展 通配符 它是由shell解析,并且一般用于匹配文件名,实际上就是shell解释器去解析的特殊符号,linux系统通配符有几下几种:

符号

含义

*

匹配任意多个字符

?

匹配任意一个字符

匹配中括号内出现的任意一个字符

!…

不匹配中括号内出现的任意一个字符

一般出现在要shell命令或脚本中,匹配特定的文件名

正则表达式 它是一个字符匹配标准,一些命令工具按此标准实现字符匹配,根据命令支持的匹配功能可分为基础正则表达式和扩展正则表达式,常用于支持正则表达式的工具,如sed,grep,awk… 有如下一些常用的匹配元字符:

字符匹配

符号

含义

.

匹配任意单个字符

*

匹配其前面一个字符出现0个或多个

?

匹配其前面的字符1次或0次

+

匹配其前面一个字符出现至少一次(在扩展正则表达式中)

位置匹配

符号

含义

^

锚定行首

$

锚定行尾

\<或\b

锚定词首,其后面的任意字符必须作为单词首部出现

>或\b

锚定词尾,其前面的任意字符必须作为单词尾部出现

\B

非单词的开头或结尾

^$

空白行

分组() : (ab)* : 匹配ab这个分组出现任意次 \1:引用第一个左括号以及与之对应的右括号所包括的所有内容,同理还有\2,\3

例如:有个文件test的内容如下: ert fff ** [abcfd] 123 324 444 [rty] ** fgfgf 怎么能截取 [abcfd] 123 324 444 [rty] 这一部分出来呢? 答案: sed -n ‘/[abcfd]/,/[rty]/p’ test

sed中,使用\u表示大写,\l表示小写 1. 把每个单词的第一个小写字母变大写: sed ‘s/\b[a-z]/\u&/g’ filename 如果不加\b那么每个字母都会变成大写,\b就近匹配,比如\bAB 匹配A,AB\b 匹配B;但如果只写一个\b或者在两个字母、数字、汉字、下划线之间有\b时就在所有字符或者两个字母、数字、汉字、下划线之间所有字符去逐个匹配

  1. 把所有小写变大写: sed ‘s/[a-z]/\u&/g’ filename
  2. 大写变小写: sed ‘s/[A-Z]/\l&/g’ filename

sed在文件中某一行最后添加一个数字

sed删除某关键字的下一行到最后一行

用sed打印1到100行包含某个字符串的行 sed -n ‘1,100{/abc/p}’ 1.txt

awk用print打印特殊字符,在awk中使用脱义字符\是起不到作用的,要使用‘“ ”’组合,如‘“$”’就能脱义$,注意:要想输出这个特殊符号记得再加上“”,如“‘“$”’”。

把两个文件中行数相同的行合并成一行 paste filename1 filename2

awk 中使用外部shell变量 说明:-v选项用于定义参数。有多少个变量需要赋值,就需要多少个-v选项。与之等价的:应用于脚本中:

#! /bin/bash
sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
        echo "[$id]"
        awk -v id2=$id -F ':' '$1==id2 {print $2}' filename  
done

awk 合并一个文件 如把两个文件中,第一列相同的行合并到同一行中。 解释:NR表示读取的行数,FNR表示读取的当前行数。NR=FNR表示读的是第一个文件,比如读到第一行NR=1,FNR也=1,也就是说在第一个文件的时候NR始终是等于FNR的,直到读第二个文件的第一行的时候NR是等于5的,而此时NFR=1,所以NR>NFR就表示在读第二个文件。{a[1]=1]=2}这个就表示在读一个文件的时候每读一行就把第二列的数据存到数组a里,{print 0,a[0,a[1]}这个就是在读第二个文件的时候把第二个文件的每一行输出并输出数组a

把一个文件多行连接成一行 awk ‘{printf(“%s “,$0)}’ file // %s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有 cat file |xargs

awk中gsub函数的使用 awk ‘gsub(/www/,”abc”)’ /etc/passwd // passwd文件中把所有www替换为abc awk -F ‘:’ ‘gsub(/www/,”abc”,$1) {print $0}’ /etc/passwd // 替换$1中的www为abc

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
        done
done

grep 或 egrep 或awk 过滤两个或多个关键词 grep -E ‘123|abc’ filename // 找出文件(filename)中包含123或者包含abc的行

egrep ‘123|abc’ filename //用egrep同样可以实现

awk ‘/123|abc/’ filename // awk 的实现方式

用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行。 1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101 2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101

#! /bin/bash

for 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`"
done

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux学习第十篇:find命令,文件名后缀

    find命令 find命令用于查找文件系统中的指定文件 其命令格式为   find 要查找的路径 -name  查找文件名  例如   find . -na...

    用户1215343
  • linux学习第十一篇:linux和Windows互传文件,用户配置文件和密码配置文件,用户组管理以及用户管理

    linux和Windows互传文件 先使用命令yum install -y lrzsz安装 PS:前提是使用xshell或者securecrt。putty不支持...

    用户1215343
  • linux学习第十三篇:su命令,sudo命令,限制root远程登录

    su命令 su - user1  //彻底切换用户,如果没有加“-”,切换用户不彻底。 su  -c  "touch /tmp/1.txt"  user1   ...

    用户1215343
  • 一道关于文件批量查找并替换内容并移动文件且将其按规则重命名的面试题

    版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢

    耕耘实录
  • 用户及组管理useradd、userdel、groupadd、groupdel

    关于“|”: head前面的“|”叫做管道符。它的作用是把前面命令的输出再输入给后面的命令。 注意: 1)管道命令只处理前一个命令正确输出,不处理错误输出...

    阿dai学长
  • Java规则引擎drools:drt动态生成规则并附上具体项目逻辑

    由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面。

    ydymz
  • 如何在大量jar包中搜索特定字符

    工作中定位某些问题时需要在jar包中搜索某些特定的字符。如果jar包数量比较少可以直接使用JD-GUI等反编译软件导出源码,但是如果jar包数目庞大,这种方式工...

    用户1221057
  • nginx+php-fpm故障排查

    小明初到一家公司做运维的工作,刚来的第一天就开始部署LNMP(Linux+Nginx+MySQL+PHP)环境,结果出现了问题。 他来向我请教。

    [3306 Pai ] 社区
  • 携程、阿里、京东、腾讯iOS春招面试过程以及面试题总结!

    五一假期,春招基本上已经结束了,剩下少量面试和少量流程中。虽然还没有最终决定,不过也还是决定来开个帖子,写一些总结。

    iOSSir
  • LeetCode 366. 寻找二叉树的叶子节点(上下翻转二叉树+BFS)

    Michael阿明

扫码关注云+社区

领取腾讯云代金券