三、linux sed命令详解

目录

3. sed【擅长取行】

3.1 sed格式说明

3.2 常见参数用法举例

3.3 s###替换标记:【flags标记】

3.3.1 s替换脚本命令

3.3.2 案例【sed 'script' inputfile】

3.3.3 补充

3.4 高级信息替换方式

3.4.1 后项引用前项进行替换

3.5 g,w,p,a,i,c,y,r,f,d 脚本命令

3.6 sed实例


3. sed【擅长取行】

        sed 是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间” ,接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。

  • 简介:常用来做行数据增删改查(最擅长取行)
  • 格式:sed [option]... 'script' inputfile
  • 翻译:sed [选项] [脚本文件] 文件名

3.1 sed格式说明

格式:sed [option]... 'script' inputfile

选项【opyion】:

  • -n        取消默认输出信息(屏幕上不显示)
  • -f         /PATH/SCRIPT_FILE:从指定文件中读取编辑脚本
  • -r         可以识别正则表达式
  • -i          直接编辑文件(慎用)
  • -i.bak   备份文件并原处编辑
  • -e        识别多个匹配条件或指令

指令信息:

  • p         打印输出指定信息,追加到默认输出之后(匹配成功的内容追加到文本最后)
  • d         删除匹配的信息,并立即启用下一轮循环
  • a         添加指定信息在某行下面,支持使用\n实现多行追加
  • i          添加指定信息在某行上面
  • s###    实现替换信息功能,支持其他分隔符,s@@@,s///
  • c          将一行进行修改替换
  • w         保存匹配的行至指定文件
  • r          在指定行后插入xx文本中所有内容
  • q         截至到选定的script 地址时命令终止
  • =         为模式空间中的行打印行号
  • !        模式空间中匹配行取反处理  

script 地址范围(选择第几行

  • 不给地址:对全文进行处理
  • 单地址: 

                         #:指定的行

                         $:最后一行

                         /pattern/:被此模式所能够匹配到的每一行

  • 地址范围:

                        #,#

                        #,+#

                        /pat1/,/pat2/

                        #,/pat1/

  • ~:步进

                       1~2  奇数行

                        2~2 偶数行

3.2 常见参数用法举例

删除操作注意事项:在删除数据或者修改数据信息时,不要同时使用 -i 和 -n 参数

-n --- 取消默认输出
-r --- 识别正则符号
-i --- 直接编辑文件(永久修改)
-i.bak --- 操作文件前以.bak结尾的文件备份(以任意字符结尾都可以)
-e --- 识别多个匹配条件或指令



# 1. 根据指定内容过滤单行信息
[root@hero ~]# sed -n '/python/p' /oldboy/oldboy.txt    
01 python

# 2. 根据指定内容进行过滤多行内容
[root@hero ~]# sed -n '/linux/,/shell/p' /oldboy/oldboy.txt 
03 linux
04 PHP
05 shell

# 3. 根据指定内容进行取反过滤(使用正则符号)
[root@hero ~]# sed -rn '/^#|^$/!p' /etc/selinux/config 
SELINUX=disable
SELINUXTYPE=targeted 

# 4. 删除文件指定内容(不做备份处理)
[root@hero ~]# sed -i '/python/d' /oldboy/oldboy.txt 
[root@hero ~]# cat /oldboy/oldboy.txt 
02 mysql
03 linux
04 PHP
05 shell
06 c++
07 c
08 c#

# 5. 删除文件指定内容(做备份处理)
[root@hero ~]# sed -i.bak '/linux/d' /oldboy/oldboy.txt 
[root@hero ~]# ll /oldboy/oldboy.txt.bak 
-rw-r--r--. 1 root root 52 3月  15 17:26 /oldboy/oldboy.txt.bak

# 6. 在指定文件看后面添加多行
[root@hero ~]# sed -e '4 a oldboy01' -e '4 a oldboy02' /oldboy/oldboy.txt
02 mysql
04 PHP
05 shell
06 c++
oldboy01
oldboy02
07 c
08 c#

3.3 s###替换标记:【flags标记】

# 格式1

$ sed 's#原有内容#修改后内容#' 文件名

------------------------------------------------------

# 格式2

$ sed 's/原有内容/修改后内容/' 文件名

------------------------------------------------------

# 格式3

$ sed 's@原有内容@修改后内容@' 文件名

  • 数字 1~512 同一行中第几次出现,例如s/a/x/2,能匹配上的只有 aaa 中间的a,数字代表第二次出现
  • g 选择的行内全局替换(否则匹配行内第一个)
  • p 显示替换成功的行
  • w /PATH/TO/SOMEFILE 将替换成功的行保存至文件中
  • & 用正则表达式匹配的内容进行替换;
  • \n 选中的行内匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。
  • \ 转义(转义替换部分包含:&、\ 等)。

3.3.1 s替换脚本命令

格式:

sed '[address-range|patttern-range] s/original-string/replacement-string/[substitute-flags] inputfile'

解释:

  • address-range:地址列表,表示从哪个地方开始执行,如:1,3 表示第1行到第 3 行;
  • pattern-range:样式列表,表示从哪个匹配串开始,如:/Jane/,表示从行中包含字符串 Jane 的行开始执行
  • s:表示要执行替换命令(substitute);
  • original-string:需要被替换的字符串 ;
  • replacement-strings:替换后的字符串;
  • substitute-flags:可选替换标志符。

注意:如果没有[address-range|pattern-range],默认选择全文进行替换

  • d表示删除
  • $表示行尾
  • ^表示开头
  • \s空白符正则
  • \s*表示连续空格的字符串

3.3.2 案例【sed 'script' inputfile】

[root@hero ~]# cat /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager

# 1. 把第一行的zhangsan 替换成 nini
[root@hero ~]# sed '1 s#zhangsan#lili#' /oldboy/oldgirl.txt 
101,nini,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Mangager

# 2. 把2~5行的Manager 替换成 nini
[root@hero ~]# sed '2,5 s#Manager#nini#' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT nini
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler nini 

# 3. 把zhangsan 所在字符串行当中的 CEO 替换成 XXX
[root@hero ~]# sed '/zhangsan/ s#CEO#XXX#' /oldboy/oldgirl.txt 
101,zhangsan,XXX
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 

# 4. 从第四行而且包含字符串‘Ram’的行中,把 Developer 字符串替换成 XXX
[root@hero ~]# sed '4,/zhaoliu/ s#Development#XXX#' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,XXX
105,Jan,Saler Manager

# 5. 如果没有 address-range 和 pattern-range,那么就会把每一行碰到的第一个匹配字符串给替换掉
[root@hero ~]# sed 's#1#AAA#' /oldboy/oldgirl.txt 
AAA01,zhangsan,CEO
AAA02,lisi,IT Manager
AAA03,wangwu,Sysadmin
AAA04,zhaoliu,Development
AAA05,Jan,Saler Manager 

# 6. s###后的数字标记 1,2,3 把要匹行中第 n 个符合条件的匹配串替换成我们想要的字符串
# 把每一行第二个匹配的1,进行替换
[root@hero ~]# sed 's#1#AAA#2' /oldboy/oldgirl.txt 
10AAA,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 

# 7. 将 origin-string 替换到 replace-string
[root@hero ~]# sed 's#zhangsan#[&]#' /oldboy/oldgirl.txt 
101,[zhangsan],CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager

3.3.3 补充

# 用文本模式指定行区间
grep daemo /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologi

# 用正斜线将要指定的 pattern 封起来,sed 会将该命令作用到包含指定文本模式的行上。

# 在包含'demo'的行中,进行s替换
$ sed '/demo/s/bash/csh/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
demo:x:502:502::/home/demo:/bin/csh
...

3.4 高级信息替换方式

3.4.1 后项引用前项进行替换

三、linux sed命令详解_第1张图片(借用老男孩教育的图片)

格式:sed 's#(.*)#\1#g' 文件名。 在这里,(.*)所匹配的就是\1的内容

# 1. 把连续的数,使用“,”两两分为一组
[root@hero ~]# echo 123456|sed -r 's#(..)(..)(..)#\1,\2,\3#g'
12,34,56
[root@hero ~]# echo 123456|sed -r 's#(..)(..)(..)#\3,\2,\1#g'
56,34,12

3.5 g,w,p,a,i,c,y,r,f,d 脚本命令

g 全局替换

# g 全局标志会把遇到的所有的满足条件的字符串给替换掉

[root@hero ~]# sed 's#1#AAA#g' /oldboy/oldgirl.txt 
AAA0AAA,zhangsan,CEO
AAA02,lisi,IT Manager
AAA03,wangwu,Sysadmin
AAA04,zhaoliu,Development
AAA05,Jan,Saler Manager 

w 输出到文本

# 把每行碰到第一个字符串 zahngsan 替换成 nini 字符串,并写入 output.txt 中,不写数字默认就是第一个匹配到的

[root@hero ~]# sed 's#1#AAA#2w /oldboy/output.txt' /oldboy/oldgirl.txt 
10AAA,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 
[root@hero ~]# cat /oldboy/output.txt 
10AAA,zhangsan,CEO

p 标记会输出修改过的行

# 3. -n -p (-n 选项会禁止sed输出,但p标记会输出修改过的行)

[root@hero ~]# sed -n 's#1#AAA#2p' /oldboy/oldgirl.txt 
10AAA,zhangsan,CEO

a 命令追加行(在匹配内容后面追加)

[root@hero ~]# cat /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 

# 1. 在行尾追加XXX
[root@hero ~]# sed '$ a XXX' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 
XXX

# 2. 在文本匹配处的下面增加
[root@hero ~]# sed '/wangwu/ a \AAA\BBB' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin
AAABBB
104,zhaoliu,Development
105,Jan,Saler Manager

# 3. 在文本匹配处的下面增加多行
[root@hero ~]# sed '2 a AAA\nBBB' /oldboy/oldgirl.txt    --- \n 表示回车到下一行
101,zhangsan,CEO
102,lisi,IT Manager
AAA
BBB
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager

i 命令插入行(在匹配内容前面插入)

# 1. 在第二行的前面添加AAA
[root@hero ~]# sed '2 i AAA' /oldboy/oldgirl.txt 
101,zhangsan,CEO
AAA
102,lisi,IT Manager
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager 

使用 c 命令修改所在行

# 1. 把“lisi”所在行替换成“AAA”
[root@hero ~]# sed '/lisi/ c AAA' /oldboy/oldgirl.txt 
101,zhangsan,CEO
AAA
103,wangwu,Sysadmin
104,zhaoliu,Development
105,Jan,Saler Manager

使用 y 命令作字符转换

[root@hero ~]# cat /oldboy/oldbaby.txt 
abcdef 
1234

[root@hero ~]# sed 'y#abc#ABC#' /oldboy/oldbaby.txt 
ABCdef 
1234

使用 q 命令终止执行

示例: sed '3 q' input-file 执行完第3行后终止

格式:sed '/Anand/ q' input-file 匹配到Anand行后退出

# 1. 执行到第3行后结束
[root@hero ~]# sed '3 q' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager
103,wangwu,Sysadmin

# 2. 执行到“lisi” 后结束
[root@hero ~]# sed '/lisi/ q' /oldboy/oldgirl.txt 
101,zhangsan,CEO
102,lisi,IT Manager

r 将文件中的内容插入到匹配位置后

# 0. 前期准备
[root@hero ~]# cat /oldboy/data12.txt 
This is an added line.
This is the second added line.

[root@hero ~]# cat /oldboy/data6.txt 
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.

# 1. sed 命令会将 filename 文件中的内容插入到 address 指定行的后面,比如说:
[root@hero ~]# sed '3r /oldboy/data12.txt' /oldboy/data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an added line.
This is the second added line.
This is line number 4.

# 2. 如果你想将指定文件中的数据插入到数据流的末尾,可以使用 $ 地址符,例如:
[root@hero ~]# sed '$r /oldboy/data12.txt' /oldboy/data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is an added line.
This is the second added line.

f 插入并使用sh脚本

[root@hero ~]# cat /oldboy/test.txt 

First Wed

h1Helloh1
h2Helloh2
h3Helloh3



[root@hero ~]# cat /oldboy/sed.sh 
/h[0-9]/{
    s//\<&\>/1
    s//\<\/&\>/2
}

#使用正则表示式给所有第一个的h1、h2、h3添加<>,给第二个h1、h2、h3添加
[root@hero oldboy]# sed -f sed.sh test.txt 

First Wed

Hello

Hello

Hello

d 删除脚本命令

当和指定地址一起使用时,删除命令显然能发挥出大的功用。可以从数据流中删除特定的文本行。
# 1. 通过行号指定,比如删除 data6.txt 文件内容中的第 3 行:
[root@hero ~]# cat /oldboy/data6.txt 
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
[root@hero ~]# sed '3d' /oldboy/data6.txt 
This is line number 1.
This is line number 2.
This is line number 4.

# 2. 或者通过特定行区间指定,比如删除 data6.txt 文件内容中的第 1~3行:
[root@hero ~]# sed '1,3d' /oldboy/data6.txt 
This is line number 4.

# 3. 或者通过特殊的文件结尾字符,比如删除 data6.txt 文件内容中第 3 行开始的所有的内容:
[root@hero ~]# sed '3,$d' /oldboy/data6.txt 
This is line number 1.
This is line number 2.

3.6 sed实例

查看某段时间内的日志:

# sed -n '/开始时间日期/,/结束时间日期/p' xx.log | grep “包含的关键字”
$ sed -n '/2018-06-21 14:30:20/,/2018-06-21 16:12:00/p' log.txt | grep 'keyword'

# 时间里有/的要用转意字符\转意
$ sed -n '/2022\/10\/26 14:27:16/,/2022\/10\/26 18:27:16/p' wrapper.log | grep 'POST'

# 对日志模糊查询
$ sed -n ‘/2022-10-24 21*/,/2022-10-24 22*/p’ xx.log

# 日志导出
$ sed -n ‘/2019-10-24 22:16:21/,/2019-10-21 20:16:58/p’ all.log > yoyo.log

将文本前三位数截取出来,并加上大括号,去掉后面的全部内容

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#1. 正则表达式的()前要加转义符\   \(\)
#2. (^[0-9]*\),.* 解释:以0-9开头的0个或多个元素 逗号 .*任意字符出现0次或多次
#3. \1 解释:\1指的是转义括号所捕获的字符
$ sed 's@\(^[0-9]*\),.*@{\1}@g' example.txt
$ sed 's/\(^[0-9]*\),.*/{\1}/g' example.txt
{101}
{102}
{103}
{104}
{105}

# 深入了解  \n 
$ echo 'abcabcabc' | sed 's@\(ab\)c@\1@'
ababcabc
$ echo 'abcabcabc' | sed 's@\(ab\)c@\1@g'
ababab
$ echo 'abcabcabc' | sed 's@\(ab\)\(c\)@\1d\2@g'
abdcabdcabdc

去掉注释行和空行(^$表示空行)

# -i直接编辑文件 -e多点编辑
$ sed -i -e 's/^#.*//g; /^$/d'

行首添加 # 

# 1~3行首添加#
sed 1,3 s/^/#/g
#12345
#23456
#34567
45678

你可能感兴趣的:(Linux运维,linux,服务器,运维)