Shell—3.文本处理
行过滤
- grep是行过滤工具 用于根据关键字进行行过滤
- 1.语法: grep 【选项】'关键字' 文件名
- 2.显示颜色小技巧
| 单条命令生效 grep --color=auto 'root' /etc/passwd
| 临时生效命令 alias grep='grep --color=auto'
| 永久生效编辑 /etc/bashrc 文末加上条命令;退出执行 source /etc/bashrc
- 3.选项参数
| -i 不区分大小写
| -v 查找不包含指定内容的行 反向选择
| -w 按单词搜索
| -o 打印匹配关键字
| -c 统计匹配到的次数
| -n 显示行号
| -r 逐层遍历目录查找
| -A 显示匹配行及后面多少行
| -B 显示匹配行及前面多少行
| -C 显示匹配行前后多少行
| # 以上三个应用场景 是检索日志文件关键信息
| -l 只列出匹配的文件名
| -L 列出不匹配的文件名
| -e 使用正则匹配
| -E 使用扩展正则匹配
| ^key 以关键字开头
| key$ 以关键字结尾
操作示例
[root@wg ~]# grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@wg ~]# grep -nC 3 '^root' /etc/passwd
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
[root@wg ~]# grep -n 'bash$' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
[root@wg ~]# grep -nB 5 '^ftp' /etc/passwd
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
- 过滤的时候,不加其他情况,只过滤完全匹配
列截取
- cut工具 截取字段
- 语法:cut 【选项】【文件名】
- 选项
| -c 以字符为单位进行分割,截取
| -d 自定义分割符 默认\t
| -f 与-d一起使用 指定截取哪个区域
操作示例
[root@wg ~]# cut -d: -f1 /etc/passwd
# 用冒号分割passwd文件 可以有三种方式表现冒号
| 1.直接跟在d后边
| 2.空格":"
| 3.空格':'
# 同理 -f 后边跟 1 就是取第1列
[root@wg ~]# cut -d: -f1,7 passwd
# 冒号分割,第1列和第7列
[root@wg ~]# cut -c1-5 passwd
[root@wg ~]# cut -c10- passwd
# -c按字符截取;截取1到5;从10以后全部
- CentOS6查看运行级别有两种方式,7没文件
| runlevel命令
| /etc/inittab 配置文件
[root@wg ~]# runlevel | cut -c3
[root@wg ~]# runlevel | cut -d' ' -f2
# 截取和过滤
grep -v '^#' /etc/inittab | cut -d: -f2
# -v取反 #号开头 过滤 第二行
grep '^id' /etc/inittab | cut -d: -f2
# id开头的 :过滤 第二行
grep 'initdefault:$' /etc/inittab | cut -c4
# 引号内结尾的 截取第4个字符
grep 'id:' /etc/inittab | cut -d: -f2
# 提取有id:的行 然后截取用冒号分割后的第二个字段
cut -d ':' -f2 /etc/inittab |grep -v ^#
# 过滤出冒号分割的第二列 但是整个文件都会被打印 然后再管道符 反选不是#号开头的
# grep的关键字可以加双引号 单引号 或者不加
cut -c4 /etc/inittab | tail -1
# 显示文件最后一行 管道符前是截取第四个字符
cat /etc/inittab | grep -v '^#' | cut -d: -f2 # 这个不推荐 搞笑了
cut -d: -f2 /etc/inittab | tail -1
cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1
# 提取路径是bash的非root用户的第一列
- cut命令的局限
| df -h | grep "sda5" | cur -d -f 5
| 无法提取,df的输出是用空格做分割符
| cut必须用制表符或者特殊符号作为分割符的才能使用
格式化输出
- printf是格式化输出命令
| printf '输出类型输出格式' 输出内容
| %ns: 输出字符串 n是数字 指代输出几个字符
| %ni: 输出整数 n是数字 指代输出几个数字
| %m.nf: 输出浮点数。m和n指代输出位数;如%8.2f 表示8位数,小数2位
[root@wg ~]# printf '%s%s%s\n' 1 2 3 4 5 6
123
456
- 常用的三种输出格式
| \n 换行
| \r 回车
| \t 水平输出退格键
- printf 后边不能直接加文件名
| printf '%s' $(cat student.txt)
- 在awk中支持print和printf命令
| print: 会在每个输出之后自动加入一个换行符 linux默认没有print
| printf: 标准格式输出,不会自动加入换行符;如需换行,手工加入换行符
- awk和sed是shell三剑客之二,内容较多,另起篇章
排序命令
- sort【选项】文件名
- 将文件的每一行作为一个单位,从首字符向后,依次按ASCII码值比较,按升序输出
| -f 忽略大小写
| -n 以数值型进行排序,默认使用字符串型排序
| -r 反向排序即降序
| -t 指定分隔符,默认分隔符是制表符
| -k n[,m] 指定的子范围排序 从第n字段开始 m字段结束 默认是到行尾
| -u 去除重复行
| -o 将排序结果输出到文件中,类似重定向符号 >
| -b 忽略前导空格
| -R 随机排序,每次运行的结果均不同
[root@wg ~]# sort -t ":" -k 3,3 /etc/passwd
# 指定分隔符是 ":" 只用第三字段排序
head passwd > 1.txt # 先将前10行重定位到1.txt中
sort -n -t: -k3 1.txt # 与n不同,k后跟数值;按第3列数值排序
sort -n -t: -k3 1.txt -o 2.txt # 重定向到2.txt文件
sort -u 2.txt # 去重后排序
去重
- uniq工具 仅用于去除连续重复的行
- uniq【选项】【文件】
- -i 忽略大小写
- -c 统计重复行次数
- -d 只显示重复行
重定向
- tee 从标准输入读取并写入到标准输出和文件
| 即 双向覆盖重定向(屏幕输出|文本输入)
| -a 双向追加重定向
echo hello world|tee ll.txt
echo hello world|tee -a ll.txt
# 追加了一行
合并文件
- paste工具用于合并文件行
- -d 自定义间隔符 默认是tab 分隔符可以模仿其他工具的处理方式
- -s 串行处理 非并行
paste file1 file2 # 合并了两个文件的相同行
paste -s file1 file2 # 串行处理只是把空行的归并到上一行
字符转换
- tr 用于字符转换 替换和删除 主要用于删除文件中控制字符或进行字符转换
- commands | tr 'string1' 'string2' # 把字符串1 替换成字符串2
- tr 'string1' 'string2' < filename # tr处理的内容来自于文件
- tr options 'string1' < filename # 匹配string1进行相应操作,如删除操作
- -d 删除字符串1中所有输入字符
- -s 删除所有重复出现字符序列 只保留第一个;即将重复出现字符串压缩为一个字符串
tr 'a-z' 'A-Z' < 1.txt # 将文件中所有小写字母替换成大写字母
tr ':/' '#' < 1.txt # 将:和/替换为#
tr -d ':/ 0-9,' < 1.txt # 删除文件里的字符
tr -d '[:/ 0-9,]' < 1.txt # 这种写法也可以
tr -s 'a-z' < 1.txt # 压缩连在一起的重复小写字母
--- cut、tee和tr联合示例 ---
- 提取ip地址
[root@wg ~]# ifconfig eth0 | grep 'Bcast' | cut -d: -f2 | tr -d 'a-zA-Z '
[root@wg ~]# ifconfig eth0 | grep 'Bcast' | cut -d: -f2 | cut -d' ' -f1
[root@wg ~]# ifconfig eth0 | grep 'Bcast' | tr -d 'a-zA-Z:' | cut -d' ' -f1
# 这里空格是个坑 需要留意 -f1搞不出来
[root@wg ~]# ifconfig eth0 | grep 'Bcast' | tr -d 'a-zA-Z:' | tr ' ' '\n' | grep -v '^$'
- 提取mac地址
[root@wg ~]# ifconfig eth0 | grep 'HW' | tr -s ' ' | cut -d' ' -f5
- 提取passwd文件中普通用户 并把结果保存到新的文件中
[root@wg ~]# grep 'bash$' passwd | grep -v 'root' | cut -d: -f1,2,7|tr ':' '\t' | tee abc.txt
统计命令
wc 【选项】 文件名
- -l 只统计行数
- -w 只统计单词数
- -m 只统计字符数
文件比较
- diff工具 用于逐行比较文件的不同
- 描述两个文件不同并表述怎样改变第一个文件之后与第二个文件匹配
[root@wg ~]# diff 1.txt 2.txt
| 结果 1c1,2 # 表示 第1个文件的第一行需要改变(c=change)才能和第二个文件的第1行到第2行匹配
| 结果 < aaaa # 表示 小于号'<' 表示左边文件(file1)文件内容
| 结果 ------ # 表示 分割符
| 结果 > aaa # 表示 大于号'>' 表示右边文件(file2)文件内容
| 结果 3d3 # 表示 第一个文件的第三行删除(d=delete)后才能和第二个文件的第三行匹配
| 结果 5d4 # 表示 第一个文件的第五行删除后才能和第二个文件的第四行匹配
| 结果 6a6,7 # 表示 第一个文件的第六行增加(a=add)内容后才能和第二个文件的第6到第7行匹配
- -c 上下文显示
[root@wg ~]# diff 1.txt 2.txt
| *** 1,6*** 表示第1个文件的1到6行
| ! 表示修改才能与第二个文件匹配
| - 表示需要删除该行才与第二个文件匹配
|
| --- 1,7--- 表示第2个文件的1到7行
| + 表示第一个文件需要加上该行才能与第二个文件匹配
- -u 合并格式显示
[root@wg ~]# diff 1.txt 2.txt
| --- file1 表示第一个文件
| +++ file2 表示第二个文件
|
| @@ -1,6 +1,7 @@ 表示1文件1到6行 表示2文件1到7行
| - aaaa 表示第一个文件删除aaaa
| + aaa 表示第二个文件增加aaa
- -q 对比两个目录的不同 diff -q dir1 dir2
- 有时候需要以一个文件为标准 去修改其他文件 并修改的地方较多时 可以通过打补丁的方式完成
- 先找出文件不同 然后输出到一个文件 -u上下文模式 -N将不存在的文件当做空文件
[root@wg ~]# diff 1.txt 2.txtdiff -uN file1 file2 > file.path
- 将不同内容补丁到文件
[root@wg ~]# patch file1 file.path
- 测试验证
[root@wg ~]# diff file1 file2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律