文本处理工具(一)
1、grep工具
1.1 grep是一个文本行过滤命令,可根据关键字进行行筛选
语法
# grep [选项] 关键字(要搜索的单词) 文件名
选项
# 常用选项:
options:
-i:不区分大小写
-v:查找不包含指定的内容,方向选择
-w:按单词搜索
-o:打印匹配关键字 (只打印关键字本身)
-c:统计匹配的次数
-n:显示行号
-r:逐层遍历查找
-A:显示匹配行及后面的多少行
-B:显示匹配行和之前的多少行
-C:显示匹配行的前后多少行
-I:只列出匹配的文件名
-L:列出不匹配的文件名
-e:使用正则匹配
-E:使用扩展正则匹配
-^key:以什么关键字开头筛选
-key$:以什么关键字结尾
^$:匹配空行
--color=auto:给查询出的结果关键字进行加颜色
例:如用grep过滤包含'a'的行并有颜色的显示'a'和对应的行数
1. 全局的、永久的生效
vi /etc/bashrc 别名文件末尾中添加,保存退出
alias grep='grep --color=auto'
2. 临时生效,只作用于当前的终端
直接在当前终端输入:
alias grep='grep --color=auto'
代码演示
# 这是一个名为passwd1测试文件,内容如下:
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/root
bin:x:2:2:deamo:/sbin/nologin
admin:3:3:ad:/var/spool/lpa:/sbin/nologin
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:qwe:/sqwe/qasd/aaa
1. 我想在文件passwd1文件中找以小写root关键字的行并打印出对应的行数
[root@localhost home]# grep -n 'root' passwd1
1:root:x:0:0:root:/root:/bin/bash/
2:opeartor:x:1:0:operater:/root:/sbin/nologin/root
2. 我想在文件passwd1文件中找root关键字的行并打印出对应的行数,不区分大小写
[root@localhost home]# grep -in 'root' passwd1
1:root:x:0:0:root:/root:/bin/bash/
2:opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
3. 我想在passwd1文件中查看关键字error前3行数据,后3行,前后3行!
[root@localhost home]# grep -wB2 'ftp' passwd1
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
------------------------------------------------------------------
[root@localhost home]# grep -wA2 'ftp' passwd1
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
----------------------------------------------------------
[root@localhost home]# grep -wC2 'ftp' passwd1
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
[root@localhost home]# grep -wC4 'ftp' passwd1
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
[root@localhost home]# grep -wC3 'ftp' passwd1
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
[root@localhost home]#
!@# 有没有发现什么问题?没错,就是当你-wC后面行数超过存在的行数时,会以空行代替,空出的行数=-wC后面数字*2-现存在的行数
4. 我想在passwd1文件中查看以root为开始,root为结尾的数据
root@localhost home]# grep -ni '^root' passwd1
1:root:x:0:0:root:/root:/bin/bash/
[root@localhost home]# grep -ni 'root$' passwd1
2:opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
[root@localhost home]#
5. 我想在passwd1文件中查看带o的关键字,并显示o单词的频率和含有o单词对应的行号
[root@localhost home]# grep -nic 'o' passwd1
4
6. 获取一行中匹配的字符前几行
[boy@localhost ~]$ cat string
asdasdasd123123
123456546qweqewq
,./,e,./,.!@#$%$
[boy@localhost ~]$ cat string | grep -o '[a-z]\{1,\}'
asdasdasd
qweqewq
e
[boy@localhost ~]$ cat string | grep -o '[0-9]\{1,\}'
123123
123456546
[boy@localhost ~]$ cat string | grep -o '^[0-9]\{1,\}'
123456546
[boy@localhost ~]$ cat string | grep -o '^[a-z]\{1,\}'
asdasdasd
2、cut工具
cut是列截取工具,用于截取列的内容
语法和选项
# cut 选项 文件名
常用选项
-c: 一字符为单位进行分割、截取
-d: 自定义分割符,默认为制表符\t
-f: 与-d一起使用,指定截取哪个区域
代码演示
passwd1文件内容如下:
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
**1. -c的使用: -c1-3 **
表示截取的是指定文件中所有行数据中字符第一个到第三个(包含)
[6]+ 已停止 vi passwd1
[root@localhost home]# cut -c1-3 passwd1
roo
ope
ftp
dbu
err
[root@localhost home]# vi passwd1
[7]+ 已停止 vi passwd1
[root@localhost home]# cut -c1-5 passwd1
root:
opear
ftp:x
dbus:
error
**2. -f的使用: cut -d : -f1,2 passwd1 **
表示截取passwd1 文件中以:为界左边第一个字符和低、第二个字符,如果有多个:一第一个为准,字符以两个::夹在一个的为一个!
-d是自定义字符为关键字
# passwd1 文件内容如下:
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
-----------------------------------------------------------------------------------------
# 代码
[root@localhost home]# cut -d: -f1 passwd1
root
opeartor
ftp
dbus
error
[root@localhost home]# cut -d: -f1,2 passwd1
root:x
opeartor:x
ftp:x
dbus:x
error:2
[root@localhost home]# cut -d: -f1,5 passwd1
root:root
opeartor:operater
ftp:ftp user
dbus:/sqwe/qasd/aaa
error:/var/spool/lpa
3、sort工具
sort是用于文件内容的行排序,以行为单位,从首字母向后按ASCLL码进行比较,默认是升序!
语法和选项
-u: 文件去重
-n: 以数字排序,默认是按字符排序
-t: 自定义关键字分隔符,类似cut的-d
-k: 取第几列,类似cut的-f
-r: 结果降序
-o: 等同于>,把结果重定向写入别的文件
-b: 忽略前置的空格
-R: 随机排序
代码演示
# sort -u passwd1 去重并升序
[root@localhost home]# sort -u passwd1
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
root:x:0:0:root:/root:/bin/bash/
[root@localhost home]#
# sort -n passwd1 以每行开头字符的ascll排序来进行升序,就是abcd......
[root@localhost home]# sort -n passwd1
dbus:x:55:dbus:/sqwe/qasd/aaa
error:2:3:error:/var/spool/lpa:/sbin/nologin
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
root:x:0:0:root:/root:/
# sort -ut: -k3 passwd1 去重并以:为分隔符取第三个字符为关键字进行升序
[root@localhost home]# sort -ut: -k3 passwd1
root:x:0:0:root:/root:/bin/bash/
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
error:2:3:error:/var/spool/lpa:/sbin/nologin
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
dbus:x:55:dbus:/sqwe/qas
# sort -urt: -k3 passwd1 去重并以:为分隔符取第三个字符为关键字进行降序
[root@localhost home]# sort -urt: -k3 passwd1
dbus:x:55:dbus:/sqwe/qasd/aaa
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
error:2:3:error:/var/spool/lpa:/sbin/nologin
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
root:x:0:0:root:/root:/bin/bash/
# sort -urt: -k3 passwd1 -o 1.txt 把排序后的结果输出到1.txt文本中,等同于>作用
[root@localhost home]# sort -urt: -k3 passwd1 -o 1.txt
[root@localhost home]# cat 1.txt
dbus:x:55:dbus:/sqwe/qasd/aaa
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
error:2:3:error:/var/spool/lpa:/sbin/nologin
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
root:x:0:0:root:/root:/bin/bash/
[root@localhost home]# sort -urt: -k3 passwd1 > 2.txt
[root@localhost home]# cat 2.txt
dbus:x:55:dbus:/sqwe/qasd/aaa
ftp:x:4:4:ftp user:/var/ftp:/sbin/nologin
error:2:3:error:/var/spool/lpa:/sbin/nologin
opeartor:x:1:0:operater:/root:/sbin/nologin/ROOT
root:x:0:0:root:/root:/bin/bash/
4. uniq工具
uniq只去重连续重复的行,不是连续重复的列!如1.txt中有111,222,111,333,333,333
它只会去重333,不会去重111
语法和选项
-i: 与grep中的-i一样,忽略大小写
-c: 与grep中的-c类似,统计重复行的次数(不管重不重复,都显示出来)
-d: 只显示重复行
代码演示
# passwd2文件内容如下:
222
111
333
333
333
aaa
bbb
aaa
aaa
ccc
ccc
# uniq -i passwd2 忽略大小写并去除连续的行数据
[root@localhost home]# uniq -i passwd2
111
222
111
333
aaa
bbb
aaa
ccc
# uniq -c passwd2 统计重复行的次数
[root@localhost home]# uniq -c passwd2
1 111
1 222
1 111
3 333
1 aaa
1 bbb
2 aaa
2 ccc
# uniq -d passwd2 仅显示重复行数据
[root@localhost home]# uniq -d passwd2
333
aaa
ccc
# 组合使用
[root@localhost home]# uniq -cd passwd2
3 333
2 aaa
2 ccc
[root@localhost home]# uniq -icd passwd2
3 333
2 aaa
2 ccc
5. tee工具
tee作用等同于>, 如:echo hello world | tee file1 表示输出终端的同时把hello world 写入到file1文件中
语法和选项
代码演示
6、diff工具
diff用于比较两个文件/目录之间的不同
如:diff file1 file2 表示file如何修改才能跟file2一样!
语法和选项
-b: 忽略对比空格
-B: 忽略对比空白行
-i: 忽略对比大小写
-w: 忽略所有的空格
-c: 上下文格式显示
-u: 合并格式显示
-q: 当比较的是两个目录下不同文件时,而不是比较两目录下文件内容的不同时用它
-N: 将不存在文件当成空文件
代码演示
- 文件内容的比较
# file1 与 file2内容如下:
aaai
bbbb
ccc
dddd
ee ee
------------------------------------------------------------ aaa
bbb
ccc
ccc
dddd
ee ee
# diff -u file1 file2 使用合并格式显示两个文件的不同
# 解读: -代表file1,+代表file2, 下面内容意思是:file1要-bbbb(删除一个bbbb)、+bbb(增加一个 bbb)、+ccc(增加一个ccc)就能和file2内容一样了! 我个人推荐这种格式,简单明了!
[root@localhost home]# diff -u file1 file2
--- file1 2020-11-28 16:04:22.955339396 +0800
+++ file2 2020-11-28 16:05:23.082708429 +0800
@@ -1,6 +1,6 @@
aaa
-bbbb
+bbb
ccc
+ccc
dddd
ee ee
- 目录下的文件的比较
[root@localhost home]# mkdir catalog1
[root@localhost home]# touch catalog1/file{1,3}
[root@localhost home]# touch catalog1/{1,3}.txt
[root@localhost home]# mkdir catalog2
[root@localhost home]# touch catalog2/file{1,4}
[root@localhost home]# diff -q catalog1 catalog2
只在 catalog1 存在:1.txt
只在 catalog1 存在:3.txt
只在 catalog1 存在:file3
只在 catalog2 存在:file4
[root@localhost home]# diff catalog1 catalog2
只在 catalog1 存在:1.txt
只在 catalog1 存在:3.txt
只在 catalog1 存在:file3
只在 catalog2 存在:file4
[root@localhost home]#
-
使用小技巧
我闷为什么要去找出两个文件的不同之处呢?那肯定是为了把他们同步成一样嘛,那为什么不直接复制一份呢?别急听我说!
如果你不再生产环境中这样搞,也没什么不可以,但是如果生产环境中服务器A和服务器B的某配置文件不同,我现在要把服务器B的配置文件同步成A一样,那就不能复制一份,因为重启会影响业务,怎么解决?找出文件不同,用打补丁方式解决!
# 代码演示: 1.把文件A和文件B取出不同之处,重定向到一个补丁文件 vi fileB: qwe asd zxc vi fileA: qwe sdf xcv diff -uN fileB fileA >file.patch # -N可有可无,不影响结果,亲测! [root@localhost home]# cat file.patch --- fileB 2020-11-28 16:57:11.860348905 +0800 +++ fileA 2020-11-28 16:56:45.198994795 +0800 @@ -1,3 +1,3 @@ qwe -sdf -xcv +asd +zxc 2.在把补丁文件打到需要同步的文件B中 # 有的centos没有patch这个命令,需要安装:yum -y install patch [root@localhost home]# patch fileB file.patch patching file fileB [root@localhost home]# diff -u fileA fileB [root@localhost home]# [root@localhost home]# cat fileB qwe asd zxc [root@localhost home]# cat fileA qwe asd zxc [root@localhost home]# **# 总结:** diff [选项] file1 file2 中 是改变file1文件去同步file2,这个要注意
7. paste工具
paste 用于合并文件行
语法和选项
-d: 自定义分隔符,默认tab
-s: 串行处理,非并行
代码演示
# 代码例子:
[root@localhost home]# cat file1
wo
nv shen
wo
nv shen
wo
nv shen
wo
nv shen
wo
[root@localhost home]# cat file2
zai ma
bu zai
chi le ma
chi le
zai gan ma ne
zai he ni lian tian
zuo wo npy hao ma
gun
hao de
[root@localhost home]# paste -d: file1 file2
wo:zai ma
nv shen:bu zai
wo:chi le ma
nv shen:chi le
wo:zai gan ma ne
nv shen:zai he ni lian tian
wo:zuo wo npy hao ma
nv shen:gun
wo :hao de
[root@localhost home]# paste -s file1 file2
wo nv shen wo nv shen wo nv shen wo nv shen wo
zai ma bu zai chi le ma chi le zai gan ma ne zai he ni lian tian zuo wo npy hao ma gun hao de
8、tr工具
tr用于字符转换、替换、删除,主要用于删除文件中控制字符或者进行字符转换
语法和选项
# 选项:
-d: 删除可以匹配string1的所有字符(删除所有)
-s: 删除可以匹配string1的重复字符行列,保留一个
# 用法有三种:
1. 对进行最后结果的数据的筛选、替换、删除操作!用于去空格,多行变一行! (侧重点:命令)
xxx |tr 'string1' 'string2' # 使用string1去匹配结果,匹配成功后用string2去替换
2. 对文件的内容进行tr处理 (侧重点:文件)
tr 'string1' 'string2' < filename
3. 带有选项的删除操作 (侧重点:删除)
tr 选项 'string1' < filename
# 常见匹配字符串:
a-z 所有小写字母
A-Z 所有大写字母
0-9 所有数字
[a-zA-Z0-9] 通配符
代码演示
# 用法1: tr 'string1' 'string2' < filename
# string1 和 string2的字符个数要一致,一对一替换
# string1 和 string2的字符个数不一致时
当string1字符数 > string2时,表示匹配到到string1的任何字符都替换为string2
当string1字符数 < string2时,如string1字符位数=1,string2字符位数=3, 会提取string2的第一 位字 符替换string1!如下图
[root@localhost home]# cat file2
zai ma? 12
bu zai! 23
chi le ma? 34
chi le! 45
zai gan ma ne? 56
zai he ni lian tian! 67
zuo wo npy hao ma? 78
gun! 89
hao de! 90
[root@localhost home]# tr '?' '??' < file2
zai ma? 12
bu zai! 23
chi le ma? 34
chi le! 45
zai gan ma ne? 56
zai he ni lian tian! 67
zuo wo npy hao ma? 78
gun! 89
hao de! 90
[root@localhost home]# tr '? ' '??' < file2
zai?ma??12
bu?zai!?23
chi?le?ma??34
chi?le!?45
zai?gan?ma?ne??56
zai?he?ni?lian?tian!?67
zuo?wo?npy?hao?ma??78
gun!?89
hao?de!?90
[root@localhost home]# tr '? ' '@' < file2
zai@ma@@12
bu@zai!@23
chi@le@ma@@34
chi@le!@45
zai@gan@ma@ne@@56
zai@he@ni@lian@tian!@67
zuo@wo@npy@hao@ma@@78
gun!@89
hao@de!@90
-----------------------------------------------------------------------------------------
[root@localhost home]# cat file2
zai ma?! 12
bu zai!! 23
chi le ma?! 34
chi le!! 45
zai gan ma ne?! 56
zai he ni lian tian!! 67
zuo wo npy hao ma?! 78
gun!! 89
hao de!! 90
# 注意:'?!'与 '@'替换过程是@先替换?再替换!,不是直接用@替换整个?!,所以‘?!’还可以加其他的字符
[root@localhost home]# tr '?!' '@' < file2
zai ma@@ 12
bu zai@@ 23
chi le ma@@ 34
chi le@@ 45
zai gan ma ne@@ 56
zai he ni lian tian@@ 67
zuo wo npy hao ma@@ 78
gun@@ 89
hao de@@ 90
# 用法2:tr -d/-s '字符' < file2
# -d 删除存在file2中的'字符'
# -s 删除存在file2中同一行中连续出现匹配'字符'的列
[root@localhost home]# cat file2
zai ma?! 12
bu zai!! 23
chi le ma?! 34
chi le!! 45
zai gan ma ne?! 56
zai he ni lian tian!! 67
zuo wo npy hao ma?! 78
gun!! 89
hao de!! 90
[root@localhost home]# tr -d '0-9' < file2 #
zai ma?!
bu zai!!
chi le ma?!
chi le!!
zai gan ma ne?!
zai he ni lian tian!!
zuo wo npy hao ma?!
gun!!
hao de!!
[root@localhost home]# tr -d 'a-z' < file2
?! 12
!! 23
?! 34
!! 45
?! 56
!! 67
?! 78
!! 89
!! 90
[root@localhost home]# tr -s ',!@#$' < file2
zai ma?! 12
bu zai! 23
chi le ma?! 34
chi le! 45
zai gan ma ne?! 56
zai he ni lian tian! 67
zuo wo npy hao ma?! 78
gun! 89
hao de! 90
[root@localhost home]#
小练习:
-
获取本机(linux)的ip地址、子网掩码、广播地址并以三行的形式展示:
思考:
-
获取linux的ip命令是ifconfig, 我的网卡是ens33 = ifconfig ens33
[root@localhost home]# ifconfig ens33 ens33: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.124.140 netmask 255.255.255.0 broadcast 192.168.124.255 inet6 fe80::fb8c:c17d:918a:f548 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:53:e2:96 txqueuelen 1000 (Ethernet) RX packets 162 bytes 49989 (48.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 -
要先获取第二行的数据,使用grep过滤
[root@localhost home]# ifconfig ens33 |grep -w 'netmask' inet 192.168.124.140 netmask 255.255.255.0 broadcast 192.168.124.255 [root@localhost home]# -
切除除去数字以外的其他字符,空格要留着,不然数字连起来会混淆
[root@localhost home]# ifconfig ens33 |grep -w 'netmask'|tr -d 'a-z' 192.168.124.140 255.255.255.0 192.168.124.255 -
使用换行符替换空格达到换行,换行后再去除所有空格就OK了
[root@localhost home]# ifconfig ens33 |grep -w 'netmask'|tr -d 'a-z'|tr ' ' '\n' 192.168.124.140 255.255.255.0 192.168.124.255 [root@localhost home]# ifconfig ens33 |grep -w 'netmask'|tr -d 'a-z'|tr ' ' '\n'|grep -v '^$' 192.168.124.140 255.255.255.0 192.168.124.255 [root@localhost home]#
-
-
获取本机(linux)的mac地址:
思考:1.获取linux的mac地址命令, 再把这行的空格列去重压缩一下,然后列截取地址就OK了
[root@localhost home]# ifconfig ens33|grep -w 'ether' ether 00:0c:29:53:e2:96 txqueuelen 1000 (Ethernet) [root@localhost home]# ifconfig ens33|grep -w 'ether'|tr -s ' ' ether 00:0c:29:53:e2:96 txqueuelen 1000 (Ethernet) [root@localhost home]# ifconfig ens33|grep -w 'ether'|tr -s ' '|cut -d' ' -f3 00:0c:29:53:e2:96 [root@localhost home]#
浙公网安备 33010602011771号