Linux三剑客

发布时间 2023-12-06 17:34:56作者: ganwong99

正则表达式

通过特殊符号的辅助,快速过滤、替换和处理所需要的字符串、文本。
需要注意的是:1.正则表达式在工作时,以行为单位,一次处理一行;2.linux中仅受sed(流编辑器)、awk(格式化文本报告生成器)、grep(文本过滤工具)三个命令的支持,其他命令无法使用。
正则表达式包括基本正则表达式和拓展正则表达式。
下面是基本正则表达式BRE(Basic Regular Expression)

符号 作用
^ 用于模式的最左侧,如"^heo",匹配以heo开头的行
$ 用于模式的最右侧,如"heo$",表示以heo结尾的行
^$ 组合符,表示空行
. 匹配任意一个且只有一个字符,不能匹配空行
|转义符,让特殊含义字符打回原型
* 匹配前一个字符0次或多次,重复0次表示空,即匹配所有内容
.* 组合符,匹配所有内容
^.* 组合符,匹配任意多个字符开头的内容,比如"^.*inet"匹配inet结尾的任意多字符开头的
.*$ 组合符,匹配任意多个字符结尾的内容
[abc] 匹配[]集合内的任意一个字符,连续也可写作[a-c]
[^abc] 匹配除了^后面的任意字符,表示对[abc]的取反

拓展正则表达式ERE(Extended Regular Expression)

符号 作用
+ 匹配前一个字符1次或多次
[?]+ 匹配括号内的":"或者"/"字符1次或多次
? 匹配前一个字符0次或1次
| 表示或者,同时过滤多个字符串
() 分组过滤,被括起来的内容表示一个整体
a 匹配前一个字符最少n次,最多m次
a 匹配前一个字符最少n次
a 匹配前一个字符正好n次
a 匹配前一个字符最多m次

Tips:
1.grep命令需要使用-E参数才能支持拓展正则表达式。

grep命令

Linux grep 命令 用于查找文件里符合条件的字符串或正则表达式。

1.-i参数忽略大小写,-n参数显示匹配行与行号
grep -i "root" pwd.txt -n 

2.-c参数统计匹配结果的行数
grep "login" /tmp/test.txt -c

3.-v参数,反向查找,只打印不匹配的行。

4.贪婪匹配
grep ".*e" test.txt 

sed命令

Linux sed 命令 是利用脚本来处理文本文件。

1.输出第2和3行
sed "2,3p" happy.txt -n #-n参数仅显示script处理后的结果,不显示默认输出

2.输出第2以及后三行(输出第2345行)
sed "2,+3p" happy.txt -n #p代表打印print

3.过滤出含有linux字符的行
sed "/linux/p" test.txt -n

4.删除含有name的行
sed "/name/d" test.txt

5.删除从第5行到末尾
sed "5,$d" test.txt

6.查找内容并替换
sed "s/My/His/g" hello.txt -i  #s表示替换操作;/My/表示要替换的文本;/His/表示要替换成的文本;/g表示全局替换,即替换所有匹配的文本。
sed -e "s/My/His/g" -e "s/189/178/g" hello.txt -i #执行多个修改时需要在每个独立的script前面加上-e参数

7.添加内容
sed "2a I am wg" info.txt -i #在第2行后面添加内容
sed "4i You are wss" info.txt -i #在第三行前添加内容
sed "4i You are wss\nHe is wb" info.txt -i #使用换行符
sed "a ------" info.txt #在每一行后面添加分割的内容

8.去头去尾
[root@localhost ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.101.233  netmask 255.255.255.0  broadcast 192.168.101.255
        inet6 fe80::61e2:8c7a:6781:b2ac  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:9d:9e:17  txqueuelen 1000  (Ethernet)
        RX packets 441688  bytes 138437829 (132.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 60926  bytes 21817712 (20.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ifconfig ens33|sed "2p" -n
        inet 192.168.101.233  netmask 255.255.255.0  broadcast 192.168.101.255
[root@localhost ~]# ifconfig ens33|sed "2p" -n |sed -e "s/^.*inet//"|sed -e "s/net.*$//"
 192.168.101.233
[root@localhost ~]# ifconfig ens33|sed "2p" -n |sed -e "s/^.*inet//" -e "s/net.*$//"
 192.168.101.233
[wg@localhost ~]$ ifconfig ens33 | sed -e "2s/^.*inet//" -e "2s/net.*$//p" -n
 192.168.101.233

awk命令

Linux awk 命令 是一种处理文本文件的语言,是一个强大的文本分析工具。

1.
[wg@localhost test]$ awk '{print $0}' test.txt # 打印test.txt的全部内容
test1 test2 test3 test4 test5
test6 test7 test8 test9 test10
test11 test12 test13 test14 test15
test16 test17 test18 test19 test20
test21 test22 test23 test24 test25
test26 test27 test28 test29 test30
test31 test32 test33 test34 test35
test36 test37 test38 test39 test40
test41 test42 test43 test44 test45
test46 test47 test48 test49 test50
[wg@localhost test]$ awk '{print $1}' test.txt #打印test.txt的分割后的第一列的内容,默认分隔符是空格
test1
test6
test11
test16
test21
test26
test31
test36
test41
test46

awk常见内置变量

内置变量 解释
$n 指定分隔符后,当前记录的第n个字段
$0 完整的输入记录
FS 字段分隔符,默认是空格
NF(number of fields) 分割后,当前行一共有多少个字段
NR(number of records) 当前记录数,行数
更多内置变量 man awk
1.输出两行内容
awk '{print $1,$5$3}' test.txt #输出第1、5、3列的内容,","代表打印时带上分隔符,不加会连在一起

2.在打印输出时添加个性化内容
[wg@localhost test]$ awk '{print "第一列:"$1,"第二列:"$2}' test.txt
第一列:test1 第二列:test2
第一列:test6 第二列:test7
第一列:test11 第二列:test12
第一列:test16 第二列:test17
第一列:test21 第二列:test22
第一列:test26 第二列:test27
第一列:test31 第二列:test32
第一列:test36 第二列:test37
第一列:test41 第二列:test42
第一列:test46 第二列:test47

3.显示文本第5行
[wg@localhost test]$ awk 'NR==5{print $0}' test.txt #awk '模式{动作}'  #NR在awk中表示行号,NR==5表示行号是5的那一行。注意:”=“是修改变量值的意思,”==“是等于的意思
test21 test22 test23 test24 test25

4.显示文本第3到6行
[wg@localhost test]$ awk 'NR==3,NR==6{print $0}' test.txt
test11 test12 test13 test14 test15
test16 test17 test18 test19 test20
test21 test22 test23 test24 test25
test26 test27 test28 test29 test30

5.给每一行添加行号
[wg@localhost test]$ awk '{print NR,$0}' test.txt
1 test1 test2 test3 test4 test5
2 test6 test7 test8 test9 test10
3 test11 test12 test13 test14 test15
4 test16 test17 test18 test19 test20
5 test21 test22 test23 test24 test25
6 test26 test27 test28 test29 test30
7 test31 test32 test33 test34 test35
8 test36 test37 test38 test39 test40
9 test41 test42 test43 test44 test45
10 test46 test47 test48 test49 test50

6.显示第3到6行且添加行号
[wg@localhost test]$ awk 'NR==3,NR==6{print NR,$0}' test.txt
3 test11 test12 test13 test14 test15
4 test16 test17 test18 test19 test20
5 test21 test22 test23 test24 test25
6 test26 test27 test28 test29 test30
 
7.显示第一列,倒数第一列和倒数第二列
[wg@localhost test]$ awk '{print $1,$NF,$(NF-1)}' test.txt
test1 test5 test4
test6 test10 test9
test11 test15 test14
test16 test20 test19
test21 test25 test24
test26 test30 test29
test31 test35 test34
test36 test40 test39
test41 test45 test44
test46 test50 test49

8.
[wg@localhost test]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.101.233  netmask 255.255.255.0  broadcast 192.168.101.255
        inet6 fe80::61e2:8c7a:6781:b2ac  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:9d:9e:17  txqueuelen 1000  (Ethernet)
        RX packets 463419  bytes 140805243 (134.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 62694  bytes 22013166 (20.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[wg@localhost test]$ ifconfig ens33|awk 'NR==2{print $2}'
192.168.101.233

awk参数

参数 解释
-F 指定字段分隔符
-v 定义或者修改一个awk的内部变量
-f 从脚本文件中读取awk命令

awk内置变量

内置变量 解释
FS 输入字段分隔符,默认为空格
OFS 输出字段分隔符,默认为空格
RS 输入记录分隔符(输入时的换行符)
ORS 输出记录分隔符(输出时的换行符),输出时用指定符号作为换行符
NF 当前行的字段个数(当前行被分割为了几列)
NR 当前处理的的文本行的行号
FNR 在同时处理多文件时,各文件分别记录行号
FILENAME 当前文件名
ARGC 命令行参数的个数
ARGV 保存的是命令行所给定的各参数

Tips:
1.awk命令的内置变量NR和NF是不需要添加$符号的

1.指定非空格的分隔符
[wg@localhost test]$ cat passwd.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
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
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
wg:x:1000:1000:wg:/home/wg:/bin/bash
[wg@localhost test]$ awk -F ':' '{print $1,$NF}' passwd.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
sshd /sbin/nologin
postfix /sbin/nologin
wg /bin/bash
[wg@localhost test]$ awk -v FS=":" '{print $1,$NF}' passwd.txt #和前面的效果是一样的,这里是修改了默认的输入分隔符FS

2.修改默认的输出分隔符OFS
[wg@localhost test]$ awk -F ':' -v OFS="---" '{print $1,$NF}' passwd.txt
root---/bin/bash
bin---/sbin/nologin
daemon---/sbin/nologin
adm---/sbin/nologin
lp---/sbin/nologin
sync---/bin/sync
shutdown---/sbin/shutdown
halt---/sbin/halt
mail---/sbin/nologin
operator---/sbin/nologin
games---/sbin/nologin
ftp---/sbin/nologin
nobody---/sbin/nologin
systemd-network---/sbin/nologin
dbus---/sbin/nologin
polkitd---/sbin/nologin
sshd---/sbin/nologin
postfix---/sbin/nologin
wg---/bin/bash

3.输出每行的行号,以及指定列
[wg@localhost test]$ awk -v FS=":" '{print NR,$1,$(NF-1)}' passwd.txt
1 root /root
2 bin /bin
3 daemon /sbin
4 adm /var/adm
5 lp /var/spool/lpd
6 sync /sbin
7 shutdown /sbin
8 halt /sbin
9 mail /var/spool/mail
10 operator /root
11 games /usr/games
12 ftp /var/ftp
13 nobody /
14 systemd-network /
15 dbus /
16 polkitd /
17 sshd /var/empty/sshd
18 postfix /var/spool/postfix
19 wg /home/wg

4.处理多个文件时显示行号
awk '{print NR,$0}' alpha.txt beta.txt #输出时,后面的beta行号会接着alpha的继续往下
awk '{print FNR,$0}' alpha.txt beta.txt #输出时,两个文件会单独计数

5.指定每行的换行符(输入、输出)
[wg@localhost test]$ awk -v RS=" " '{print NR,$0}' passwd.txt
1 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
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP
2 User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd
3 Network
4 Management:/:/sbin/nologin
dbus:x:81:81:System
5 message
6 bus:/:/sbin/nologin
polkitd:x:999:998:User
7 for
8 polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated
9 SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
wg:x:1000:1000:wg:/home/wg:/bin/bash
[wg@localhost test]$ awk -v ORS="---\n" '{print NR,$0}' passwd.txt
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---
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 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:998:User for polkitd:/:/sbin/nologin---
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin---
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin---
19 wg:x:1000:1000:wg:/home/wg:/bin/bash---

6.ARGV实例
[wg@localhost test]$ awk 'BEGIN{print "start now!"} {print ARGV[0],ARGV[1],ARGV[2]}' passwd.txt test.txt
start now!
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt
awk passwd.txt test.txt

7.自定义变量。也可以使用$value引用shell全局变量
[wg@localhost test]$ awk -v myname="wg" 'BEGIN{print "what is my name?",myname}'
what is my name? wg

printf命令

Linux printf 命令 可以进行文本格式化输出。
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。

1.进行简单的标准化输出
[wg@localhost wg_test]$ cat gushi.txt
静夜思
床前明月光
[wg@localhost wg_test]$ awk '{printf $0}' gushi.txt
静夜思床前明月光 [wg@localhost wg_test]$

2.%s替代每一行的字符串信息,\n是换行符
[wg@localhost wg_test]$ awk '{printf "%s\n",$0}' gushi.txt
静夜思
床前明月光

3.对多变量进行格式化
[wg@localhost wg_test]$ printf "%s--\n" a b c d
a--
b--
c--
d--

4.使用%d输出整型,一个%d指代一个整数,多余的没有%d的不会输出
[wg@localhost wg_test]$ awk 'BEGIN{printf "%d\n %d\n%d--\n",1,2,3,4}'
1
 2
3--

5.格式化输出,%-25s中,“-”代表左对齐(默认是右对其),“25”代表字符串长度(就是25把这个撑长了)
[wg@localhost wg_test]$ awk -F ":" 'BEGIN{printf "%-25s\t %-25s\t %-25s\t %-25s\t%-25s\t %-25s\t %-25s\n","用户名","密码","UID","GID","用户注释","用户家目录","用户使用的解释器"} {printf "%-25s\t %-25s\t %-25s\t %-25s\t%-25s\t %-25s\t %-25s\n",$1,$2,$3,$4,$5,$6,$7}' passwd.txt
用户名                           密码                            UID                             GID                            用户注释                             用户家目录                      用户使用的解释器
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
games                            x                               12                              100                            games                        /usr/games                      /sbin/nologin
ftp                              x                               14                              50                             FTP User                     /var/ftp                        /sbin/nologin
nobody                           x                               99                              99                             Nobody                       /                               /sbin/nologin
systemd-network                  x                               192                             192                            systemd Network Management   /                               /sbin/nologin
dbus                             x                               81                              81                             System message bus           /                               /sbin/nologin
polkitd                          x                               999                             998                            User for polkitd             /                               /sbin/nologin
sshd                             x                               74                              74                             Privilege-separated SSH      /var/empty/sshd                 /sbin/nologin
postfix                          x                               89                              89                                                          /var/spool/postfix              /sbin/nologin
wg                               x                               1000                            1000                           wg                           /home/wg                        /bin/bash

特殊的模式pattern:BEGIN和END

1.BEGIN模式是处理文本之前需要执行的操作。
2.END模式是处理完所有行之后执行的操作。

1.
[wg@localhost wg_test]$ awk 'BEGIN{print "magic start!"}{print $0}END{printf "%s\n","done!"}' gushi.txt
magic start!
静夜思
床前明月光
done!

正则表达式

在awk中使用正则表达式,需要把正则表达式放到“//”中,匹配到结果后,执行动作{}

1.简单的过滤,找到games开头的,输出第一列和最后一列
[wg@localhost wg_test]$ awk -F ":" '/^games/{print $1,$NF}' passwd.txt
games /sbin/nologin

2.出现/需要转义符
[wg@localhost wg_test]$ awk '/\/sbin\/nologin$/{print $0}' passwd.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
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

3.多个正则条件用“,”隔开即可。显示文本以operator开头到ftp开头的行
[wg@localhost wg_test]$ awk '/^operator/,/^ftp/{print NR,$0}' passwd.txt
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