13、Linux文本处理三剑客的组合使用示例

前几篇梳理了 sed 命令,grep命令,awk命令的用法和常用的使用场景,感受到了文本三剑客的强大和实用,接下来,根据实际用到的例子,演示下他们的组合使用场景。

示例1:批量替换多个文件中的指定内容

上篇的 a1.txt 、b1.txt 两个文件(当前目录下就这两个文件)为例,将当前目录下所有文件中 "utf" 字符串替换成 "GBK"。思路无疑是先查找再编辑,也就是说,可以使用 grep 查找再 sed 编辑,或者 grep + awk 组合查找,再 sed 编辑,这里总结了2种可行的方式。

方式一:

sed -i "s/原字符串/新的字符串/g" `grep -i 原字符串 -rl 所在目录`

测试一下,为方便测试看效果,sed 命令暂不使用 -i 参数:

$ sed 's/utf/GBK/g' `grep -i utf -rl .`
20220630075945|yyds
20220630074530|omg
20220630073754|hot hot
20220630173530|come on
20220630075242|nice
20220630080933|today
20220630162211|yesyes
20220630162900|yeah
20220630163643|yeah yeah
20220630164303|nonono
20220629110635|cctv
20220630165049|996icu
20220630165835|enenenen
20220630170545|eeeeeeee
20220630171300|fuck trump
20220630174921|GBK
20220630172112|GBK-8
20220630074530|omg
20220630173530|come on
20220629110635|cctv13
20220630171300|fuck trump
20220630172112|GBK-8

方式二:

grep -i "原字符串" -r 所在目录 |awk -F ":" '{print $1}' |sort |uniq |xargs sed -i 's/原字符串/新的字符串/g'

简单解释下:grep 命令从所在目录,进行递归查找存在"原字符串"的文件,且忽略"原字符串"大小写,查找的结果是这个格式"xxx文件:对应的行数据",而我们需要的是"xxx文件",因此,使用 awk 命令进行提取第1列的文件名,并通过 sort 命令和 uniq 命令实现排序和去重。

xargs 是什么东西?这里重点说明下,从字面看 x 是乘号,args 是参数(arguments)的简写,放在一起就是产生某个命令的参数的含义。也就是说,xargs 可读入 stdin 数据,默认以空格符和换行符去识别,将前一个命令的 stdin 数据分隔为参数。因此,上面经排序和去重的结果(即一个个文件名并以换行符分隔)就会被分隔为多个参数,提供给后面的 sed 命令继续使用。

测试一下,为方便测试看效果,sed 命令也暂不使用 -i 参数:

$ grep -i "utf" -r . |awk -F ":" '{print $1}' |sort |uniq |xargs sed 's/utf/GBK/g'
20220630075945|yyds
20220630074530|omg
20220630073754|hot hot
20220630173530|come on
20220630075242|nice
20220630080933|today
20220630162211|yesyes
20220630162900|yeah
20220630163643|yeah yeah
20220630164303|nonono
20220629110635|cctv
20220630165049|996icu
20220630165835|enenenen
20220630170545|eeeeeeee
20220630171300|fuck trump
20220630174921|GBK
20220630172112|GBK-8
20220630074530|omg
20220630173530|come on
20220629110635|cctv13
20220630171300|fuck trump
20220630172112|GBK-8

示例2:显示系统 ip

以我的虚拟机上 CentOS7.9 为例,先使用 ifconfig 命令查看网口的配置信息:

# 网口的有些信息不便于展示,使用--线替换了
$ ifconfig
ens33: flags=xxx<UP,BROADCAST,MULTICAST>  mtu ----
        inet 192.168.150.130  netmask 255.255.255.0  broadcast 192.168.150.255
        inet6 --------------------------------  prefixlen 64  scopeid ----<link>
        ether -----------------  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        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

lo: flags=xx<UP,LOOPBACK,RUNNING>  mtu -----
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x--<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 496  bytes 43280 (42.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 496  bytes 43280 (42.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=xxxx<UP,BROADCAST,MULTICAST>  mtu -----
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether -----------------  txqueuelen ---- (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        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

可以看到,我们需要的是 ens33 的第二行信息:

$ ifconfig ens33 |grep "inet "
        inet 192.168.150.130  netmask 255.255.255.0  broadcast 192.168.150.255

这里,直接使用 awk 命令提取对应列并不容易,第一感觉是空格符比较多,而且也不确定空白的地方是不是空格符呢,因此需要一个个尝试:

$ ifconfig ens33 |grep "inet " |awk -F " " '{print $1}'
inet

$ ifconfig ens33 |grep "inet " |awk -F " " '{print $2}'
192.168.150.130

$ ifconfig ens33 |grep "inet " |awk -F " " '{print $3}'
netmask

效果还不错,使用第二个命令已经达到了预期的目的,系统的 ip 显示了出来。

当然,还有其他的方式可用,比如将 ip 的前后字符串清除,那肯定只会显示 ip 了,如下:

$ ifconfig ens33 |grep "inet " |sed 's/^.*inet //g' |sed 's/ *netmask.*$//g'
192.168.150.130

示例3:指定应用的进程关闭

我们知道,杀掉一个应用的进程,需要先通过 jps 命令看下进程号,然后使用 kill -9 进程号 才能关闭掉指定应用的进程。

而实际情况中,服务器上的应用通常是采用集群方式多节点部署的。当发布补丁时,每台机器都是需要重启的,使用刚才说的这种先查后杀方式进行关闭当前进程,效率极低。因此,经常使用 shell 脚本进行操作,比如编写 stop.sh,参考如下:

#!/bin/bash


kill -9 `jps |grep '你的应用名称' |awk '{print $1}'`

最后

其实,对于 sed 命令,grep 命令和 awk 命令的组合使用场景远不止这些啦,这里只是抛砖引玉。只要掌握了它们各自的特点,并能根据特定需求进行组合使用,将会极大的提高工作效率,并减少一些多余的没必要的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值