当前位置: 首页 > news >正文

Linux基础学习笔记(十三)——文件的格式化处理

文章目录

  • 前言
  • sed命令
    • 新增或删除行
    • 以行为单位的显示和替换
    • 部分数据的查找和替换
  • awk命令
  • 文本的比对
    • diff命令
    • cmp命令
    • patch命令
  • 小结

前言

上一篇博客完成了Linux中管道命令的梳理,这篇博客梳理一下文件的格式化输出处理,对应《鸟哥的Linux私房菜》中第11章第4节

sed命令

之前介绍过Linux的基本正则,这里在正则的基础上介绍sed命令,sed命令可将数据进行替换,删除,截取,新增等。
在这里插入图片描述

一堆参数,实在看不懂,直接通过实例吧

新增或删除行

删除行数据

#删除第三行到最后一行,$代表最后一行
[root@localhost shell-learn]# nl /etc/passwd | sed '3,$d'
     1	root:x:0:0:root:/root:/bin/bash
     2	bin:x:1:1:bin:/bin:/sbin/nologin
# 删除第二行到第五行
[root@localhost shell-learn]# nl /etc/passwd | sed '2,5d'
     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

正常来说,上面的命令是要加上-e,指定交互命令的模式,但是这里没有其实也行,同时,sed后面的内容是要包含在引号中的。

新增行数据

## [n]a在指定的行数后面加上数据
[root@localhost shell-learn]# nl /etc/passwd | sed '2a drink tea'
     1	root:x:0:0:root:/root:/bin/bash
     2	bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin

## [n]i在指定的行数前面加上数据,多行用\n分割即可
[root@localhost shell-learn]# nl /etc/passwd | sed '2i drink tea ......\ndrink beer?'
     1	root:x:0:0:root:/root:/bin/bash
drink tea ......
drink beer?
     2	bin:x:1:1:bin:/bin:/sbin/nologin

以行为单位的显示和替换

替换

#将2-5行的内容,替代为No 2-5 content
# [n1,n2]c 将n1-n2的数据替换成指定内容
[root@localhost shell-learn]# nl /etc/passwd | sed '2,5c No 2-5 content'
     1	root:x:0:0:root:/root:/bin/bash
No 2-5 content
     6	sync:x:5:0:sync:/sbin:/bin/sync

显示

# 如果通过head+tail查询11~20行的数据,这样处理稍微复杂点
[root@localhost shell-learn]# nl /etc/passwd | head -n 20 | tail -n 10
    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	liman:x:1000:1000:liman:/home/liman:/bin/bash
    20	esuser:x:1001:1001::/home/esuser:/bin/bash
# 如果通过sed命令,会简单很多
# 这里指定 -n 表示是静默的方式,不将sed的每一行输出,输出在控制台
[root@localhost shell-learn]# nl /etc/passwd | sed -n '11,20p'
    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	liman:x:1000:1000:liman:/home/liman:/bin/bash
    20	esuser:x:1001:1001::/home/esuser:/bin/bash

部分数据的查找和替换

sed命令最常用,其实是查找的同时进行替换,sed可以以行为单位进行部分数据的搜寻和替代,这个功能与vi中的类似

基本命令格式如下

sed 's/要被替换的字符串/新字符串/g'

实例

# 查询man_db.conf中 包含 'MAN'的数据行
[root@localhost shell-learn]# cat /etc/man_db.conf | grep 'MAN'
# MANDATORY_MANPATH			manpath_element
# MANPATH_MAP		path_element	manpath_element
# MANDB_MAP		global_manpath	[relative_catpath]
# every automatically generated MANPATH includes these fields
#MANDATORY_MANPATH 			/usr/src/pvm3/man
MANDATORY_MANPATH			/usr/man
MANDATORY_MANPATH			/usr/share/man
MANDATORY_MANPATH			/usr/local/share/man
##通过sed命令,替换掉含有注释的数据
[root@localhost shell-learn]# cat /etc/man_db.conf | grep 'MAN' | sed 's/#.*$//g'





MANDATORY_MANPATH			/usr/man
MANDATORY_MANPATH			/usr/share/man
MANDATORY_MANPATH			/usr/local/share/man
## 利用sed命令删除空白行
[root@localhost shell-learn]# cat /etc/man_db.conf | grep 'MAN' | sed 's/#.*$//g' | sed '/^$/d'
MANDATORY_MANPATH			/usr/man
MANDATORY_MANPATH			/usr/share/man
MANDATORY_MANPATH			/usr/local/share/man
MANPATH_MAP	/bin			/usr/share/man
MANPATH_MAP	/usr/bin		/usr/share/man

直接通过sed命令修改原文件内容

sed中的-i选项,可以直接去修改指定的文件内容,而不是输出到屏幕

# 将regular_express.txt中每一行的.号替换为!
[root@localhost shell-learn]# sed -i 's/\.$/\!/g' regular_express.txt
# 在regular_express.txt最后一行加入【# this is a test】
[root@localhost shell-learn]# sed -i '$a # this is a test' regular_express.txt

这个功能非常有帮助,比如需要在指定文件的第100行后增加某些文字,如果文件过大,vim操作起来非常不方便,sed命令就能较好的满足这个场景。

awk命令

awk命令是一个比较常用的数据处理工具,sed命令是作用于整行数据的而处理,而awk比较倾向于将一行的数据分成几个数据字段来处理,这种比较适合表格类型存储的数据。通常的运作模式如下

awk '条件类型1{动作1} 条件类型2{动作2}' filename

awk主要处理每一行的字段内的数据,这些字段的默认分隔符为"空格"或"tab键"

实例

## 查询最近登录的相关信息
[root@localhost shell-learn]# last -n 5
root     pts/0        192.168.0.103    Sat Sep  3 10:21   still logged in   
reboot   system boot  3.10.0-1160.el7. Sat Sep  3 10:19 - 13:00  (02:41)    
root     pts/1        192.168.0.101    Tue Aug 23 19:31 - down   (01:44)    
root     pts/0        192.168.0.101    Tue Aug 23 19:16 - down   (01:59)    
reboot   system boot  3.10.0-1160.el7. Tue Aug 23 19:11 - 21:16  (02:04)

##awk命令,取出最近5次登录的用户名和ip地址
[root@localhost shell-learn]# last -n 5 | awk '{print $1 "\t" $3}'
root	192.168.0.103
reboot	boot
root	192.168.0.101
root	192.168.0.101
reboot	boot
	
wtmp	Sun

这里的awk命令没有加条件限制,则awk命令会处理每一行,我们想获取的是第一列和第三列,上述命令中的$1和$3,代表第一列和第三列。$0代表当前行的数据。

整个awk命令的数据处理流程是

1、读入第一行数据,并将第一行的数据一次填入,$0,$1,$2…等变量中

2、依据"条件类型"的限制,判断是否需要进行后面的处理

3、做完所有的数据处理和条件判断

4、循环处理下一行

处了$0,$1,等变量之外,还有其他几个变量

变量名称代表意义
NF每一行拥有的字段总数
NR目前awk所处理的是第几行数据
FS目前的分隔符,默认是空格或者tab

实例

[root@localhost shell-learn]# last -n 5 | awk '{print $1 "\t lines: " NR "\t columns:" NF}'
root	 lines: 1	 columns:10
reboot	 lines: 2	 columns:11
root	 lines: 3	 columns:10
root	 lines: 4	 columns:10
reboot	 lines: 5	 columns:11
	 lines: 6	 columns:0
wtmp	 lines: 7	 columns:7

其他实例

## 指定以":"为分割符,且,如果userid<10则打印第1和第3列
## 但是第一行还是显示的是原始数据,这是因为awk读入第一行数据的时候
## 还是以空格为分隔符的,虽然定义了FS= ":" 但是这个仅能在第二行开始生效
[root@localhost shell-learn]# cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t" $3}'
root:x:0:0:root:/root:/bin/bash	
bin	1
daemon	2
## 利用BEGIN这个关键词,可以让指定的分隔符第一行开始生效。
[root@localhost shell-learn]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'
root	0
bin	1
daemon	2

一个比较复杂的实例

准备一个pay.txt,内容如下
在这里插入图片描述

通过如下命令,计算每行的数值总和

[root@localhost shell-learn]# cat pay.txt | awk 'NR==1{printf "%10s,%10s,%10s,%10s,%10s\n",$1,$2,$3,$4,"Total"} NR>=2 {total = $2 + $3 + $4;printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}'

运行结果为
在这里插入图片描述

文本的比对

diff命令

在这里插入图片描述

实例

[root@localhost shell-learn]# mkdir -p /tmp/testpw
[root@localhost shell-learn]# cd /tmp/testpw/
[root@localhost testpw]# cp /etc/passwd passwd.old
[root@localhost testpw]# cat /etc/passwd | sed -e '4d' -e '6c no six line' > passwd.new
[root@localhost testpw]# ll
总用量 8
-rw-r--r--. 1 root root 907 93 14:16 passwd.new
-rw-r--r--. 1 root root 964 93 14:16 passwd.old
[root@localhost testpw]# diff passwd.old passwd.new
4d3 #old文件中的第四行被删除自后,基准是new文件的第三行
< adm:x:3:4:adm:/var/adm:/sbin/nologin ##old被删除的内容
6c5 ##old文件的第六行被取代成new文件的第五行
< sync:x:5:0:sync:/sbin:/bin/sync ## old文件中第6行的内容
---
## new文件中的第5行内容
> no six line

可以看到diff文件可以列出文件修改的历史

cmp命令

在这里插入图片描述

从文件的字节数来比较文件的差异

patch命令

在这里插入图片描述

这个命令主要用来根据diff产生的差异,构建升级包,这个后面源码编译的时候,会进一步总结

小结

基础的文本处理命令完成,后续开始总结shell的一些内容

相关文章:

  • 微信小程序开发02 授权模型: 小程序的用户体系与 OAuth 规范
  • codeforces:E. Madoka and The Best University【因数list + 分析拆解 + 公因数特性 + 欧拉函数】
  • 华为OD 社招(Java后端)一面
  • DDD - 理论到落地从统一语言开始
  • 【LeetCode 48】旋转图像
  • 计算机网络.第五节课.笔记.以太网、CSMA/CD、VLAN
  • 运行时数据区域
  • 机器学习----k-means聚类
  • 姿态分析开源工具箱MMPose使用示例:人体姿势估计
  • 如何安装虚拟机
  • ICP问题 SVD方法推导(Markdown版)
  • java基于ssm+vue+elementui的水果生鲜销售购物商城
  • kafka知识点总结
  • 【vue3】06. 跟着官网学习vue3
  • 任务十一 BERT
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 07.Android之多媒体问题
  • 5、React组件事件详解
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Otto开发初探——微服务依赖管理新利器
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 翻译:Hystrix - How To Use
  • 和 || 运算
  • 少走弯路,给Java 1~5 年程序员的建议
  • 十年未变!安全,谁之责?(下)
  • 提醒我喝水chrome插件开发指南
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​渐进式Web应用PWA的未来
  • ​香农与信息论三大定律
  • # 数据结构
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转载)OpenStack Hacker养成指南
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .NET CORE 第一节 创建基本的 asp.net core
  • .Net 高效开发之不可错过的实用工具
  • .NET与 java通用的3DES加密解密方法
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • @SentinelResource详解
  • [\u4e00-\u9fa5] //匹配中文字符
  • [android学习笔记]学习jni编程
  • [AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现
  • [delphi]保证程序只运行一个实例
  • [GXYCTF2019]BabySQli1
  • [hdu 3652] B-number
  • [IDF]啥?
  • [iOS]如何删除工程里面用cocoapods导入的第三方库