目录
1、文本处理工具
1.1、grep[过滤出行]
1.2、grep使用
1.3、cut【截取列】
1.4、练习1
1.4、sort【排序,去重】
1.5、uniq工具【去重】
1.6、tee工具【结果屏幕输出一份,文件输出一份】
1.6、diff工具【比较两个文件内容的异同】
1.7、paste工具【合并文件行】
1.8、tr工具【用于字符的转换】
1.9、练习2
1.10、练习3
1、文本处理工具
Linux中最重要的三个命令在业界被称为“三剑客”,它们是awk,sed,grep。
https://blog.youkuaiyun.com/sj349781478/article/details/82930982
1.1、grep[过滤出行]
grep是行过滤工具,用于根据关键字进行行过滤。
语法:grep 【可选项】 ‘关键字’ 文件名
常见选项:
-i 忽略字符大小写
-v 查找不包含指定内容的行,反向选择
-w 按单词搜索
-o 打印匹配的关键字
-c 统计匹配到的次数
-n 显示行号
-r 逐层遍历目录查找
-A 显示匹配行以及后面多少行
-B: 显示匹配行及前面多少行
-C: 显示匹配行前后多少行
-l:只列出匹配的文件名
-L:列出不匹配的文件名
-e: 使用正则匹配
-E:使用扩展正则匹配
^key:以关键字开头
keyKaTeX parse error: Expected group after '^' at position 9: :以关键字结尾 ^̲:匹配空行
--color=auto :可以将找到的关键词部分加上颜色的显示
1.2、grep使用
1、高亮:grep --color=auto 'error' adapter.log
临时设置:alias grep='grep --color=auto'
永久高亮:
vi /etc/bashrc
最后添加:alias grep='grep --color=auto'
source /etc/bashrc
设置完后,这样也能高亮:grep 'error' adapter.log
2、过滤行并且显示行号
过滤出包含root字符串的行并且显示行号
[root@localhost ~]# grep -n 'root' test
3:2020-10-28 21:21:37.887 [main] INFO org.apache.zookeeper.ZooKeeper - Client environment:user.dir=/root/canal/adapter/bin
3、过滤出包含root字符串的行忽略大小写,并且显示行号
[root@localhost ~]# grep -ni 'root' test
2:2020-10-28 21:22:18.370 ROOT [main-SendThread(localhost:2181)] WARN org.apacheEE.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
3:2020-10-28 21:21:37.887 [main] INFO org.apache.zookeeper.ZooKeeper - Client environment:user.dir=/root/canal/adapter/bina
4、过滤出文件中以root开头的行
[root@localhost ~]# grep '^root' test
root2020-10-28 21:22:18.370 [main-SendThread(localhost:2181)] WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
5、过滤出文件中以xxx结尾的行
[root@localhost ~]# grep 'reconnect$' test
root2020-10-28 21:22:18.370 [main-SendThread(localhost:2181)] WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
2020-10-28 21:22:18.370 ROOT [main-SendThread(localhost:2181)] WARN org.apacheEE.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
6、过滤出文件中不以xxx开头的行
使用-v取反,即可
[root@localhost ~]# grep -niv '^root' test
2:2020-10-28 21:22:18.370 ROOT [main-SendThread(localhost:2181)] WARN org.apacheEE.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
3:2020-10-28 21:21:37.887 [main] INFO org.apache.zookeeper.ZooKeeper - Client environment:user.dir=/root/canal/adapter/bina
7、过滤出文件中以xxx开头的前x行,后x行
-B x 过滤出关键字的前几行
[root@localhost ~]# grep -n -B 1 '^ftp' test
3-2020-10-28 21:21:37.887 [main] INFO org.apache.zookeeper.ZooKeeper - Client environment:user.dir=/root/canal/adapter/bina
4:ftp2020-10-28 21:21:37.887 [main] INFO org.apache.zookeeper.ZooKeeper - Client environment:user.dir=/root/canal/adapter/bina
-A x 过滤出关键字的后几行
-C x 过滤出关键字的前后几行
8、根据单词去过滤出文件中的行
-w 根据单词去过滤行。
[root@localhost ~]# grep -w 'hello' test
hello world
helloworld是过滤出不出来的。
9、统计文件中某个单词出现的次数
[root@localhost ~]# grep -o "a" test | wc -l
30
-o 打印匹配的关键字
| 将结果输出给下一个命令
wc 将计算指定文件的行数、字数,以及字节数。
-l 只显示行数。
10、在大日志文件中搜索关键字,最后/最开始出现位置
1、先查出关键字,前后一行的数据:grep -C 1 ‘error’ test
2、然后将结果通过|,输出给后面的tail命令去统计:grep -C 1 'error' test | tail -2
tail -2 要显示文件的最后2行
1.3、cut【截取列】
grep是行的过滤,cut是列的截取
语法:cut 选项 文件名
-c: 以字符为单位进行分割,截取
-d: 自定义分隔符,默认为制表符\t
-f: 与-d一起使用,指定截取哪个区域
1、截取:号的第一列
-d:表示使用冒号分割
-f1 表示取分割的第一列
[root@localhost ~]# cut -d: -f1 test
aaaaaaaaaaaaaaaaaaaaaaa
root2020-10-28 21
2020-10-28 21
2020-10-28 21
ftp2020-10-28 21
hello world
helloworld
2、截取:号的第一列和第七列
[root@localhost ~]# cut -d: -f1,7 test
aaaaaaaaaaaaaaaaaaaaaaa
root2020-10-28 21: Session
2020-10-28 21
2020-10-28 21
ftp2020-10-28 21
hello world
helloworld
3、截取从第一个字符到第五个字符
[root@localhost ~]# cut -c1-5 test
aaaaa
root2
2020-
2020-
ftp20
hello
hello
-c10- :表示从第十个字符开始全部截取
1.4、练习1
如何过滤出运行级别?
1、获取运行级别的方法
runlevel
[root@localhost ~]# cat /etc/inittab
2、解决:
使用cut
[root@localhost ~]# runlevel
N 3
[root@localhost ~]# runlevel | cut -d ' ' -f2
3
[root@localhost ~]# runlevel | cut -c3
3
使用grep:
[root@localhost ~]# grep '^id' /etc/inittab | cut -c4
3
[root@localhost ~]# grep -v '^#' /etc/inittab | cut -c4
3
[root@localhost ~]# grep 'initdefault:$' /etc/inittab | cut -c4
3
1.4、sort【排序,去重】
sort工具用于排序;它将文件的每一行作为一个单位,从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
语法和选项:
-u :去除重复行
-r :降序排列,默认是升序
-o : 将排序结果输出到文件中,类似重定向符号>
-n :以数字排序,默认是按字符排序
-t :分隔符
-k :第N列
-b :忽略前导空格。
-R :随机排序,每次运行的结果均不同
使用例子:
1、对文件排序
-n 使用数字排序
-t:使用冒号作为分隔符号
-k2 表示按照第二列来排序
[root@localhost ~]# sort -n -t: -k2 1.txt
asdas:111
123:123
ss123:222
asd:333
456:456
789:789
1.5、uniq工具【去重】
uniq用于去除连续的重复行
常见选项:
-i: 忽略大小写
-c: 统计重复行次数
-d:只显示重复行
实例:uniq只去除连续重复的行
[root@localhost ~]# uniq 1.txt
123:123
456:456
789:789
asdas:111
ss123:222
asd:333
456:456
[root@localhost ~]# cat 1.txt
123:123
123:123
456:456
789:789
asdas:111
ss123:222
asd:333
456:456
1.6、tee工具【结果屏幕输出一份,文件输出一份】
tee工具是从标准输入读取并写入到标准输出和文件,即:双向覆盖重定向(屏幕输出|文本输入),简单说,就是屏幕打印一份,文件里一份
标准输入:键盘输出的就是,文件的内容也是
标准输出:屏幕上,文件
默认是覆盖,想要追加,使用选项
>:表示覆盖原文件内容
>>:这个是将输出内容追加到目标文件中。如果文件不存在,就创建文件;如果文件存在,则将新的内容追加到那个文件的末尾,该文件中的原有内容不受影响;
区别:tee可以把一份数据同时写入几个文件中,而>>只能把一份数据写入到一个文件中;
选项:
-a 双向追加重定向
使用例子:
1、将标准的输入读取并写到文件中,默认覆盖
[root@localhost ~]# echo hello world |tee 1.txt
hello world
[root@localhost ~]# cat 1.txt
hello world
2、追加
[root@localhost ~]# echo hello world |tee -a 1.txt
hello world
[root@localhost ~]# cat 1.txt
hello world
hello world
1.6、diff工具【比较两个文件内容的异同】
diff工具用于逐行比较文件的不同。
注意:diff描述两个文件不同的方式是告诉我们怎样改变第一个文件之后与第二个文件匹配。
语法:
diff [选项] 文件1 文件2
常用选项:
-b不检查空格
-B不检查空白行
-i不检查大小写
-w忽略所有的空格
--normal正常格式显示(默认)
-c上下文格式显示
-u合并格式显示
1、正常模式:
diff目的:file1如何改变才能和file2匹配
比较难看懂
[root@MissHou ~]# diff file1 file2
1c1,2第一个文件的第1行需要改变(c=change)才能和第二个文件的第1到2行匹配
< aaaa小于号"
------表示分隔符
> aaa大于号">"表示右边文件(file2)文件内容
> hello
3d3第一个文件的第3行删除(d=delete)后才能和第二个文件的第3行匹配
< hello world
5d4第一个文件的第5行删除后才能和第二个文件的第4行匹配
< 333
6a6,7第一个文件的第6行增加(a=add)内容后才能和第二个文件的第6到7行匹配
> 333需要增加的内容在第二个文件里是333和world
> world
[root@localhost shellDemo]# cat file1
aaaa
111
hello world
222
333
bbb
[root@localhost shellDemo]# cat file2
aaa
hello
111
222
bbb
333
world
2、上下文格式显示:
[root@MissHou ~]# diff -c file1 file2
前两行主要列出需要比较的文件名和文件的时间戳;文件名前面的符号***表示file1,---表示file2
*** file1 2019-04-16 16:26:05.748650262 +0800
--- file2 2019-04-16 16:26:30.470646030 +0800
***************我是分隔符
*** 1,6 ****以***开头表示file1文件,1,6表示1到6行
! aaaa!表示该行需要修改才与第二个文件匹配
111
- hello world-表示需要删除该行才与第二个文件匹配
222
- 333-表示需要删除该行才与第二个文件匹配
bbb
--- 1,7 ----以---开头表示file2文件,1,7表示1到7行
! aaa表示第一个文件需要修改才与第二个文件匹配
! hello表示第一个文件需要修改才与第二个文件匹配
111
222
bbb
+ 333表示第一个文件需要加上该行才与第二个文件匹配
+ world表示第一个文件需要加上该行才与第二个文件匹配
3、合并格式显示:
[root@MissHou ~]# diff -u file1 file2
前两行主要列出需要比较的文件名和文件的时间戳;文件名前面的符号---表示file1,+++表示file2
--- file1 2019-04-16 16:26:05.748650262 +0800
+++ file2 2019-04-16 16:26:30.470646030 +0800
@@ -1,6 +1,7 @@
-aaaa
+aaa
+hello
111
-hello world
222
-333
bbb
+333
+world
4、比较两个文件,并把文件2的不同的地方,以打补丁的方式,打到文件1中去,使两个文件的内容一样
先找出文件的不同,然后将结果输出到一个文件file3,file3就是补丁文件
diff -u file1 file2 > file3
打补丁
patch file1 file3
验证:
[root@localhost shellDemo]# diff file1 file2
[root@localhost shellDemo]# cat file1
aaa
hello
111
222
bbb
333
world
[root@localhost shellDemo]# cat file2
aaa
hello
111
222
bbb
333
world
5、比较两个目录不同
默认情况下也会比较两个目录里相同文件的内容
[root@MissHou tmp]# diff dir1 dir2
diff dir1/file1 dir2/file1
0a1
> hello
Only in dir1: file3
Only in dir2: test1
如果只需要比较两个目录里文件的不同,不需要进一步比较文件内容,需要加-q选项
[root@MissHou tmp]# diff -q dir1 dir2
Files dir1/file1 and dir2/file1 differ
Only in dir1: file3
Only in dir2: test1
1.7、paste工具【合并文件行】
paste工具用于合并文件行
常用选项:
-d:自定义间隔符,默认是tab
-s:串行处理,非并行
例:
默认是以制表符分割
[root@localhost shellDemo]# paste file1 file2
aaa aaa
hello hello
111 111
222 222
bbb bbb
333 333
world world
指定分割符号:
[root@localhost shellDemo]# paste -d: file1 file2
aaa:aaa
hello:hello
111:111
222:222
bbb:bbb
333:333
world:world
串行处理:
[root@localhost shellDemo]# paste -s file1 file2
aaa hello 111 222 bbb 333 world
aaa hello 111 222 bbb 333 world
1.8、tr工具【用于字符的转换】
tr用于字符转换,替换和删除;主要用于删除文件中控制字符或进行字符转换
语法:
用法1:命令的执行结果交给tr处理,其中string1用于查询,string2用于转换处理
commands|tr 'string1' 'string2'
用法2:tr处理的内容来自文件,记住要使用"
tr 'string1' 'string2' < filename
用法3:匹配string1进行相应操作,如删除操作
tr [options] 'string1' < filename
常用选项:
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串
常匹配字符串:
a-z或[:lower:] 匹配所有小写字母
A-Z或[:upper:] 匹配所有大写字母
0-9或[:digit:] 匹配所有数字
[:alnum:] 匹配所有字母和数字
[:alpha:] 匹配所有字母
[:blank:] 所有水平空白
[:punct:] 匹配所有标点符号
[:space:] 所有水平或垂直的空格
\n Ctrl-J 换行
\r Ctrl-M 回车
\t Ctrl-I tab键
例子:
1、把文件中的字母全部转成大写,并输出到控制台
[root@localhost shellDemo]# tr 'a-z' 'A-Z'
AAA
HELLO
111
222
BBB
333
WORLD
[root@localhost shellDemo]# tr [:lower:] 'A-Z'
AAA
HELLO
111
222
BBB
333
WORLD
2、把文件中的数字全部转成@,并输出到控制台
[root@localhost shellDemo]# tr '0-9' '@'
aaa
hello
@@@
@@@
bbb
@@@
3、把文件中的:和/全部转成#,并输出到控制台
[root@localhost shellDemo]# tr ':/' '#'
aaa
hello
111
222
bbb
333
world
54#asd#12123
00#olosd#111
4、删除文件中的小写字母
[root@localhost shellDemo]# tr -d 'a-z'
111
222
333
54:/12123
00:/111
1.9、练习2
截取出当前主机的ip,子网掩码和网络地址。
实现:
ifconfig ens33:查看ip,子网掩码和网络地址
grep 'netmask':筛选出含’netmask’字符串的行
tr -d 'a-zA-Z':删除文件中的小写字母大写字母
tr ' ' '\n':将空格替换为换行
grep -v '^$':找出所有的空行^$,然后取反
[root@localhost shellDemo]# ifconfig ens33 | grep 'netmask'| tr -d 'a-zA-Z' | tr ' ' '\n' | grep -v '^$'
192.168.169.129
255.255.255.0
192.168.169.255
获取物理地址:
tr -s ' ' :压缩空格
cut -d' ' -f3:截取列
[root@localhost shellDemo]# ifconfig ens33 |grep 'ether' | tr -s ' '| cut -d' ' -f3
00:0c:29:18:27:a5
1.10、练习3
将系统中所有普通用户的用户名、密码和默认shell保存到一个文件中,要求用户名密码和默认shell之间tab键分割
1、查看用户
UID来区分普通用户和系统用户,即UID大于999的为普通用户,否则为系统用户。
[root@localhost shellDemo]# cat /etc/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
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
lzh:x:1000:1000:lzh:/home/lzh:/bin/bash
sonar:x:1001:1001::/home/sonar:/bin/bash
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
2、编写
grep 'bash$':过滤出所有一bash结尾的行
grep -v 'root':过滤掉root用户
cut -d: -f1,2,7:以冒号来截取列,截取1,2,7列
tr ':' '\t' :将冒号换成制表符
tee abc.txt:输出到文件同时控制台输出看一下
[root@localhost shellDemo]# grep 'bash$' /etc/passwd | grep -v 'root' |cut -d: -f1,2,7| tr ':' '\t' | tee abc.txt
lzh x /bin/bash
sonar x /bin/bash
[root@localhost shellDemo]# cat abc.txt
lzh x /bin/bash
sonar x /bin/bash