Linux sed

在Linux中,sed是Stream Editor(流式编辑器)的缩写,所谓的流式编辑器就是不像vim这种编辑器一样一次性将所有文件内容读取到内存中。而是将文本内容一行一行读取到内存中进行处理。读取一行就处理一行,直到全部处理完成;

sed这个工具一般在shell脚本里面使用比较多,用来非交互式修改文件内容。


工作原理

  1. 运行sed命令后,操作系统就启动了一个sed进程,会给这个sed进程分配内存空间,这个内存空间分为两部分。一部分叫做模式空间,另外一部分叫做保持空间。

  2. 编辑文件的时候,会将硬盘中的文件内容一行行读到内存(模式空间),然后进行处理后输出。


使用格式

          sed  [option]  '处理方法'  /path
  • 处理方法说明:处理方法 = 定位 + 操作

  • 定位:匹配到指定的内容(对哪行内容作什么样的处理)

  • 操作:具体做什么处理,例如删除、修改、替换等。


例如:

sed '' 1.txt

# 没有指定处理方法,会将文件的内容原样输出到屏幕;

常用选项

  1. -r或-E: 表示支持扩展正则,类似于grep的 -E 选项,sed默认只支持基本正则

  2. -i:表示对文件进行修改,流出到屏幕的内容会流入到屏幕里面去。这样就实现了文件的修改

  3. -n:表示取消模式空间的默认输出,模式空间默认就是输出到屏幕上的

  4. -e:可以对指定内容作多次处理,也可以将多个处理之间使用分号(;)分隔,效果等通过-e选项;


处理方法

上面我们说了sed的处理方法由两部分组成,定位和操作,定位表示要对那行内容进行处理,操作表示要对定位到的内容做什么样的处理。


数据定位方式

行号定位

特点:直接指定行号,通过行号来定位指定的行,从而进行处理

  匹配单行:例如:sed '6CMD' /path 表示匹配到第6行时,就使用CMD命令进行处理。

  匹配范围:例如:sed '6,9CMD' /path 表示匹配6-9行时,就使用CMD命令进行处理


正则定位

特点:通过正则匹配到对应的行

格式:'/正则表达式/CMD'

  例如:sed '/tom/命令' /path 表示匹配含有tom的行,使用CMD命令进行处理

  说明:两个斜杠的作用就是起分隔的效果,当然也可以换成其它符号。例如:ed '@.*@命令' /path


两者结合定位

例如:sed '3,/tom$/' 表示从第三行开始,到以tom结尾的行的这个范围;


数据处理方式

用于对定位到的指定内容做相关操作;

  • p 输出指定的行内容到屏幕

  • s 用于实现替换操作,语法: 's/需要替换的/替换后的'

  • c 替换某一行的内容

  • d 匹配到指定行,就将该行删除,不输出到屏幕

  • a 再某些行后面加内容

  • i 再某些行前面加内容

  • g 全部替换,一般结合s命令就行使用。


范例

输出文本文件中第二行的内容

sed -n '2p' 1.txt
# 加-n就是取消默认的输出,默认会把所有内容都输出到屏幕上

输出以root开头的字符的行到屏幕上

 sed -n '/^root/p' 1.txt

输出第三行到第六行的内容

sed -n '3,6p' /etc/passwd

输出奇数行内容

sed -n '1~2p' /etc/passwd
# 从1开始,每次的增量都是2 即 1 3 5 7 9 ...

包含nologin的内容都删除,不输出到屏幕

sed  '/nologin$/d' passwd
# 源文件不会发生改变的

把每行的第一个nologin替换为login

sed  's/nologin/login/' 1.txt

# 不指定范围,就是全部都匹配
# 没有加g参数,只会替换每行中第一个匹配到的指定字符,如果一行有多个相同的内容,只会替换最左边的一个。如果向全部替换,需要加g命令

将每行中的每个nologin替换为login

sed  's/nologin/login/g' 1.txt

将指定行内容全部替换

sed -i '/^#set_var EASYRSA_CA_EXPIRE/c\set_var EASYRSA_CA_EXPIRE      36500'  /etc/openvpn/rsa-server/vars

# /^#set_var EASYRSA_CA_EXPIRE/表示通过正则匹配以xxx开头的行
# c\set_var EASYRSA_CA_EXPIRE      36500'  表示替换后的内容
#  /etc/openvpn/rsa-server/vars是文件名

# 转义字符的作用是确保 c\xxxxxx被正确解释为替换内容,而不是被解释为其他特殊含义的字符。

c操作和s操作的区别:

c操作是将匹配到的行进行整体替换,s操作是将匹配到的内容进行替换更改。


取匹配到的内容

通过 & 符号表示的就是获取前面匹配到的内容,当然也可以使用扩展正则表达式的小括号,结合\n来获取指定括号中的内容。

一般使用后者就行了。这种方法叫作正则表达式的分组(后项引用),即通过小括号实现分组,后面要表示第几个分组的内容就用 \num(第几个小括号里面的内容,从而实现把一个文件的一行切成多块,保留其中所需部分。


将非#开头的行加#

sed -rn 's/^[^#](.*)/#\1/p' /etc/fstab

selinux配置修改

sed -r -i '/^SELINUX=/s/(SELINUX=).*/\1disabled/' /etc/selinux/config

获取网卡ip地址

ifconfig  eth0 | sed -rn '2s/(.*inet )([0-9].*)(netmask.*)/\2/p'
10.0.0.22

在行尾的数字后面加 .change

sed 's/[0-9]$/&.change/'

使用变量

正常情况下sed的命令格式是 sed [option] '处理方法' filename 处理方法部分是用单引号引起来的,就是怕shell把这里面的字符当成通配符给解释了。这样也就造成了一个问题,在里面用shell的变量,变量就没法替换为具体的值。

解决方法: 使用双引号来将处理方法括起来,但是如果里面有一些特殊字符,需要使用转义字符 \ 进行转义,不然会被shell当成通配符解释。

shell一般会解释以下一些字符:
这些字符在shell里面具有特殊的意义,所以如果sed使用的时候,没有才取强引用,需要使用转义字符来进行转义才行。

$ --- 变量引用,

反引号 --- 命令替换

| --- 管道符

& --- 后台运行命令

*、?、[ ] --- 通配符

{} --- 扩展符

>,<,<<,>> --- 重定向

; --- 命令分隔符

() --- 组合命令

posted on 2022-07-11 16:03  背对背依靠  阅读(528)  评论(0编辑  收藏  举报