12.shell sed文本处理工具

1.sed基本概述
sed是一个流编辑器,能够处理特别大的文件,
能够对标准输出或文件进行逐行处理,
简单来说sed可以实现对文件内容的过滤、替换、增、删、改、查。

2.sed的工作模式
sed读取一行,存放在缓存区,然后处理,最后输出。
它是一行一行载入内存的,不像vim一次将文件全都载入内存,内存不足的情况下直接卡死。
所以编辑大文件sed更合适。

3.sed基础语法
形式一:stdout | sed [选项] "匹配方式 命令"
形式二:sed [选项] "匹配方式 命令" file

sed学习步骤:

option 选项
pattern 匹配方式
command 命令

例:变更selinux配置文件的内容(变更文件内容的方式)

   sed -i  '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config
   
   匹配/etc/selinux/config文件中以SELINUX=开头的行,替换为SELINUX=enforcing
   
   -i 选项
   // pattern匹配
   c  command动作 c表示替换

sed option 选项
选项含义
-n只打印匹配的行(取消文件的默认输出,只打印过滤的那行)
-e允许编辑多项
-f把pattrn保存在文件,指定文件才执行
-r支持扩展正则表达式
-i直接变更文件内容

sed 选项示例

示例文件:

cat file.txt

I love shell
I love SHELL
This is test file

sed -n选项示例
取消默认输出
sed -n '/shell/p' file.txt
在这里插入图片描述

sed -e选项示例
编辑多项
sed -n -e '/shell/p' -e '/SHELL/p' file.txt
在这里插入图片描述

sed -f选项示例
把pattern写在文件中,-f指定文件,调用文件中的匹配
sed -n -f sed.txt file.txt
在这里插入图片描述

sed -r选项示例
支持扩展正则表达式
sed -nr '/shell|SHELL/p' file.txt
在这里插入图片描述


sed pattern 匹配

命令格式:sed [option] '/pattern/command' file
在这里插入图片描述

sed 匹配示例

打印/etc/passwd文件中的第10行
sed -n '10p' /etc/passwd
在这里插入图片描述

打印/etc/passwd文件中的第10行到第15行结束
sed -n '10,15p' /etc/passwd
在这里插入图片描述

打印/etc/passwd文件中的第10行开始到后面5行结束
sed -n '10,+5p' /etc/passwd
在这里插入图片描述

打印/etc/passwd中开头匹配bin字符串的内容
sed -n '/^bin/p' /etc/passwd
在这里插入图片描述

打印/etc/passwd中开头为root的行开始,到开头为ftp的行结束的内容
sed -n '/^root/,/ftp/p' /etc/passwd
在这里插入图片描述

打印/etc/passwd中第10行开始,到含有ftp的内容的行结束的内容
sed -n '10,/ftp/p' /etc/passwd
在这里插入图片描述

打印/etc/passwd中第8行开始,到含有/sbin/nologin的内容的行结束内容,这里/需要转义一下
sed -n '8,/\/sbin\/nologin$/p' /etc/passwd
在这里插入图片描述


sed command 命令
追加 
删除
替换

追加

命令含义
a行后追加内容
i行前追加内容
r读入外部文件,行后追加
w将匹配行写入外部文件

例:修改ssh配置文件,在第16行后追加下列三行内容,\n换行

Port 666
AddressFamily any
UseDNS no

#举例说明使用场景
sed -i '16a Port 666\nAddressFamily any\nUseDNS no' /etc/ssh/sshd_config
追加示例

a 行后追加内容
匹配/bin/bash的行,在其行后追加一行内容
sed -i '/\/bin\/bash/a sed test' passwd
在这里插入图片描述

i 行前添加内容
以/bin开头的行到以sshd开头的行,前面添加一行
sed '/^bin/,/^sshd/i sed TEST' passwd
在这里插入图片描述

i 行前添加内容
指定给文件的第30行添加一行内容
sed '30i this is a test' passwd
如果要修改文件内容的话,前面再加上-i选项
在这里插入图片描述

r 读取外部文件 行后追加
将sed.txt中的内容,追加到匹配的行后面
sed '/^wang/r sed.txt' passwd
在这里插入图片描述
在这里插入图片描述

w 将匹配行写入外部文件
匹配/bin/bash所有的行,将其保存至当前路径下的login.txt文件中
sed '/\/bin\/bash/w ./login.txt' passwd
在这里插入图片描述


替换示例

在这里插入图片描述

修改passwd文件第一行第一个root为ROOT
sed '1s/root/ROOT/' passwd在这里插入图片描述
加g代表替换这行所有的匹配内容,不加就只替换第一个
sed '1s/root/ROOT/g' passwd
在这里插入图片描述

修改passwd文件第1行到第10行中所有的/sbin/nologin为/bin/bash
sed '1,10s/\/sbin\/nologin/\/bin\/bash/' passwd

当遇到需要转义的时候会看起来很乱
可以用#或者@代替/
符号之间相互替换,更方便查看

效果一样
sed '1,10s#/sbin/nologin#/bin/bash#' passwd
sed '1,10s@/sbin/nologin@/bin/bash@' passwd

在这里插入图片描述

修改passwd文件中匹配到/sbin/nologin的行,将匹配到行中的login为该大写的LOGIN
sed '/\/sbin\/nologin/s#login#LOGIN#g' passwd
在这里插入图片描述

修改passwd文件中从匹配到以root开头的行,到匹配到行中包含bin的所有行,将bin改为BIN
sed '/^root/,/bin/s/bin/BIN/g ' passwd
在这里插入图片描述

5.修改SELINUX=enforcing修改为SELINUX=disabled (可以使用c替换方式)
sed ‘/^SELINUX=/s/enforcing/disabled/g’ selinux

sed ‘/^SELINUX=/c SELINUX=disabled’ selinux

将nginx.conf配置文件添加注释
sed 's/^/#/' nginx.conf
在这里插入图片描述

使用sed提取ens192网卡的IP地址
ifconfig ens192|sed -rn '2s/^.*et //p'|sed -rn 's/ ne.*//p'
在这里插入图片描述

ifconfig ens192|sed -rn '2s/(^.*et) (.*) (net.*)/\2/p'
在这里插入图片描述


删除示例
命令含义
1d删除第1行的内容
1,5d删除1行到5行的内容
2,+5d删除2行以及往下的5行的内容
/pattern1/d删除每行中匹配到pattern1的行内容
/pattern1/,/pattern2/d删除匹配到pattern1的行直到匹配到pattern2的所有行内容
/pattern1/,10d删除匹配到pattern1的行到10行的所有行内容
10,/pattern1/d删除第10行直到匹配到pattern1的所有内容

删除/etc/passwd中的第15行
sed '15d' passwd

删除/etc/passwd中的第8行到第14行的所有内容
sed '8,14d' passwd

删除/etc/passwd中以/sbin/nologin结尾的行
sed '/\/sbin\/nologin$/d' passwd

删除/etc/passwd中以bin开头的行,到以ntp开头的行的所有内容
sed '/^bin/,/^ntp/d' passwd

删除/etc/passwd中第3行到以ftp开头的所有行内容
sed '3,/^ftp/d' passwd

典型需求:删除Nginx配置文件中所有的注释以及空行
sed -ri '/^#|^$/d' nginx.conf

在这里插入图片描述


sed相关脚本

处理一个ansible的invtory主机清单。
1.输出主机组,一对 [ ] 为一个主机组。
2.输出每个主机组下的主机总个数。
3.输出主机组下,每台主机的地址。

示例文件:

[webservers]
192.168.10.10
192.168.10.11
192.168.10.12
192.168.10.13
192.168.10.14

[proxy]
192.168.10.15
192.168.10.16
192.168.10.17
192.168.10.18
192.168.10.19

1.想办法输出主机组名称
打印以[开头的行,然后去掉[ ]就是我们要的主机名
sed -n '/^\[/p' hosts |sed -r 's#\[|\]##g'
在这里插入图片描述

2.输出每个主机组下的主机总个数

sed -n '/\[webservers\]/,/^\[/p' hosts | sed -r '/\[|^$/d'|wc -l
在这里插入图片描述

sed -n '/\[proxy\]/,/^\[/p' hosts | sed -r '/\[|^$/d'|wc -l
在这里插入图片描述

这里可以用传参的方式代替主机组名
sed -rn '/\['$1'\]/,/^\[/p' hosts | sed -r '/^\[|^$/d' | wc -l
在调用函数的时候传参

脚本:

#!/bin/bash

get_groupname (){
	sed -n '/^\[/p' hosts | sed -r 's#\[|\]##g'
}

get_hostnum () {
	sed -rn '/\['$1'\]/,/^\[/p' hosts | sed -r '/^\[|^$/d'  | wc -l
}

for host in $(get_groupname)
do
	echo "主机组名: $host$host 中包含 $(get_hostnum $host) 台主机"

done

脚本执行效果:
在这里插入图片描述


3.输出主机组下,每台主机的地址。
sed -n '/\[webservers\]/,/^\[/p' hosts | sed -r '/\[|^$/d'| xargs |sed 's/ /\,/g'
在这里插入图片描述

#!/bin/bash

get_groupname (){
	sed -n '/^\[/p' hosts | sed -r 's#\[|\]##g'
}

get_hostnum () {
	sed -rn '/\['$1'\]/,/^\[/p' hosts | sed -r '/^\[|^$/d'  | wc -l
}

get_host () {
	sed -rn '/\['$1'\]/,/^\[/p' hosts | sed -r '/^\[|^$/d'  | xargs |sed 's/ /\,/g'
}

for host in $(get_groupname)
do
	echo "主机组名: $host$host 中包含 $(get_hostnum $host) 台主机 ,主机地址:$(get_host $host)"

done

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值