Linux学习-14-Linux文本处理命令(sed)

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 Linux学习-14-Linux文本处理命令(sed),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

6.7 sed命令

  • Vim 采用的是交互式文本编辑模式,你可以用键盘命令来交互性地插入、删除或替换数据中的文本,而sed 命令不同,它采用的是流编辑模式,最明显的特点是,在 sed 处理数据之前,需要预先提供一组规则,sed 会按照此规则来编辑数据。

  • sed 会根据脚本命令来处理文本文件中的数据,这些命令要么从命令行中输入,要么存储在一个文本文件中,此命令执行数据的顺序如下:

    1. 每次仅读取一行内容;
    2. 根据提供的规则命令匹配并修改数据。注意,sed 默认不会直接修改源文件数据,而是会将数据复制到缓冲区中,修改也仅限于缓冲区中的数据;
    3. 将执行结果输出。
  • 当一行数据匹配完成后,它会继续读取下一行数据,并重复这个过程,直到将文件中所有数据处理完毕。

  • sed 命令的基本格式如下:

[root@CncLucZK ~]# sed [选项] [脚本命令] 文件名
  • 该命令常用的选项及含义:
选项 含义
-e 脚本命令 该选项会将其后跟的脚本命令添加到已有的命令中。
-f 脚本命令文件 该选项会将其后文件中的脚本命令添加到已有的命令中。
-n 默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出。
-i 此选项会直接修改源文件,要慎用。
  • 成功使用 sed 命令的关键在于掌握各式各样的脚本命令及格式,它能帮你定制编辑文件的规则。
6.7.1 sed脚本命令
  • sed s 替换脚本命令:此命令的基本格式为
[address]s/pattern/replacement/flags

其中,address 表示指定要操作的具体行,pattern 指的是需要替换的内容,replacement 指的是要替换的新内容。

  • 常用的 flags 标:
flags 标记 功能
n 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记;
g 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A;
p 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。
w file 将缓冲区中的内容写到指定的 file 文件中;
& 用正则表达式匹配的内容进行替换;
\n 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。
\ 转义(转义替换部分包含:&、\ 等)。
  • 指定 sed 用新文本替换第几处模式匹配的地方
[root@CncLucZK test]# sed 's/备份/back/2' demo.txt  #会将文本全部内容输出
...
1. 容灾back:为云盘创建快照,再使用快照创建云盘获取基础数据,实现同城容灾和异地容灾。
...

使用数字 2 作为标记的结果就是,sed 编辑器只替换每行中第 2 次出现的匹配模式

  • -n 选项会禁止 sed 输出,但 p 标记会输出修改过的行,将二者匹配使用的效果就是只输出被替换命令修改过的行,

[root@CncLucZK test]# sed -n 's/备份/back/p' demo.txt
1. 快照提供了一种便捷通用的back方式,用户通过设置自动快照策略,可以实现云服务器上的磁盘自动化数据备份;
1. 容灾back:为云盘创建快照,再使用快照创建云盘获取基础数据,实现同城容灾和异地容灾。
  • w 标记会将匹配后的结果保存到指定文件中,
[root@CncLucZK test]# sed -n 's/备份/back/w replace.txt' demo.txt
[root@CncLucZK test]# cat replace.txt
1. 快照提供了一种便捷通用的back方式,用户通过设置自动快照策略,可以实现云服务器上的磁盘自动化数据备份;
1. 容灾back:为云盘创建快照,再使用快照创建云盘获取基础数据,实现同城容灾和异地容灾。
  • 在使用 s 脚本命令时,替换类似文件路径的字符串会比较麻烦,需要将路径中的正斜线进行转义,例如:
[root@CncLucZK test]# sed 's/users\/u1/users\/uu1/' demo.txt
6.7.2 sed d 替换脚本命令
  • 此命令的基本格式为:
[address]d
  • 如果需要删除文本中的特定行,可以用 d 脚本命令,它会删除指定行中的所有内容。但使用该命令时要特别小心,如果你忘记指定具体行的话,文件中的所有内容都会被删除,举个例子:
[root@CncLucZK test]# cat demo2.txt
hello world!
123456abcdef
12345ABCDEF


[root@CncLucZK test]# sed 'd' demo2.txt
#什么也不输出,证明成了空文件
[root@CncLucZK test]# sed '4d' demo2.txt
hello world!
123456abcdef
12345ABCDEF

#少了第4行
[root@CncLucZK test]# sed '3,4d' demo2.txt	#通过特定行区间指定,比如删除 data6.txt 文件内容中的第 2、3行:
hello world!
123456abcdef


[root@CncLucZK test]# cat demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
[root@CncLucZK test]# sed '/2/,/4/d' demo2.txt  #也可以使用两个文本模式来删除某个区间内的行,但这么做时要小心,你指定的第一个模式会“打开”行删除功能,第二个模式会“关闭”行删除功能,因此,sed 会删除两个指定行之间的所有行(包括指定的行),
hello world!
aaaaaaaaaa
sssssssssss
qqqqqqqqq						#删除第 2~4 行的文本数据
[root@CncLucZK test]# sed '/4/,/6/d' demo2.txt 		
[root@CncLucZK test]# sed '3,$d' demo2.txt  #通过特殊的文件结尾字符,比如删除 demo2.txt 文件内容中第 3 行开始的所有的内容
hello world!
123456abcdef

当和指定地址一起使用时,删除命令显然能发挥出大的功用。可以从数据流中删除特定的文本行。

默认情况下 sed 并不会修改原始文件,这里被删除的行只是从 sed 的输出中消失了,原始文件没做任何改变。

6.7.3 sed a 和 i 脚本命令
  • a 命令表示在指定行的后面附加一行,i 命令表示在指定行的前面插入一行,这 2 个脚本命令基本格式完全相同,如下所示:
[address]a(或 i)\新文本内容
  • 例如,执行命令如下:
#将一个新行插入到数据流第三行前
[root@CncLucZK test]# sed '3i\sed i脚本命令' demo2.txt
hello world!
123456abcdef
sed i脚本命令
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
#将一个新行附加到数据流中第三行后,执行命令如下:
[root@CncLucZK test]# sed '3a\sed i脚本命令' demo2.txt
hello world!
123456abcdef
12345ABCDE
sed i脚本命令
aaaaaaaaaa
sssssssssss
qqqqqqqqq

  • 将一个多行数据添加到数据流中,只需对要插入或附加的文本中的每一行末尾(除最后一行)添加反斜线即可,只对i有效,例如:
[root@CncLucZK test]# sed '3i\
> sed i\
> sed a' demo2.txt
hello world!
123456abcdef
sed i
sed a
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
6.7.4 sed c 替换脚本命令
  • c 命令表示将指定行中的所有内容,替换成该选项后面的字符串。该命令的基本格式为:
[address]c\用于替换的新文本
  • 例如:
[root@CncLucZK test]# sed '3c\
> sed i' demo2.txt
hello world!
123456abcdef
sed i
aaaaaaaaaa
sssssssssss
qqqqqqqqq
6.7.5 sed y 转换脚本命令
  • y 转换命令是唯一可以处理单个字符的 sed 脚本命令,其基本格式如下:
[address]y/inchars/outchars/
  • 转换命令会对 inchars 和 outchars 值进行一对一的映射,即 inchars 中的第一个字符会被转换为 outchars 中的第一个字符,第二个字符会被转换成 outchars 中的第二个字符…这个映射过程会一直持续到处理完指定字符。如果 inchars 和 outchars 的长度不同,则 sed 会产生一条错误消息。举个简单例子:
[root@CncLucZK test]# sed 'y/123/abc/' demo2.txt
hello world!
abc456abcdef
abc45ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
  • 可以看到,inchars 模式中指定字符的每个实例都会被替换成 outchars 模式中相同位置的那个字符。

  • 转换命令是一个全局命令,也就是说,它会文本行中找到的所有指定字符自动进行转换,而不会考虑它们出现的位置,再打个比方:

[root@CncLucZK test]# echo 'hello 1 world'| sed 'y/123/654/'
hello 6 world
6.7.6 sed p 打印脚本命令
  • p 命令表示搜索符号条件的行,并输出该行的内容,此命令的基本格式为:
[address]p
  • p 命令常见的用法是打印包含匹配文本模式的行,例如:
#文件内容
[root@CncLucZK test]# cat demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
#输出文件全部内容同时输出第3行内容
[root@CncLucZK test]# sed 3p demo2.txt
hello world!
123456abcdef
12345ABCDE
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
#输出文件全部内容同时输出匹配3的内容行
[root@CncLucZK test]# sed /3/p demo2.txt
hello world!
123456abcdef
123456abcdef
12345ABCDE
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
#只输出匹配3的内容行
[root@CncLucZK test]# sed -n /3/p demo2.txt
123456abcdef
12345ABCDE
#只输出第3行内容
[root@CncLucZK test]# sed -n 3p demo2.txt
12345ABCDE

用 -n 选项和 p 命令配合使用,我们可以禁止输出其他行,只打印包含匹配文本模式的行。

  • 如果需要在修改之前查看行,也可以使用打印命令,比如与替换或修改命令一起使用。可以创建一个脚本在修改行之前显示该行,如下所示:
#替换文本后输出
[root@CncLucZK test]# sed -n 's/123/321/p' demo2.txt
321456abcdef
32145ABCDE
#替换文本后在匹配3后输出
[root@CncLucZK test]# sed -n '/3/{                  
 s/123/321/p
}' demo2.txt
321456abcdef
32145ABCDE
#先输出匹配的内容,替换后文本后输出替换行
[root@CncLucZK test]# sed -n '/3/{p
 s/123/321/p
}' demo2.txt
123456abcdef
321456abcdef
12345ABCDE
32145ABCDE
#sed 命令会查找包含数字 3 的行,然后执行两条命令。首先,脚本用 p 命令来打印出原始行;然后它用 s 命令替换文本,并用 p 标记打印出替换结果。输出同时显示了原来的行文本和新的行文本。
6.7.7 sed w 脚本命令
  • w 命令用来将文本中指定行的内容写入文件中,此命令的基本格式如下:
[address]w filename

这里的 filename 表示文件名,可以使用相对路径或绝对路径,但不管是哪种,运行 sed 命令的用户都必须有文件的写权限。

  • 下面的例子是将数据流中的前3行打印到一个文本文件中:
[root@CncLucZK test]# sed '1,3w replace.txt' demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
[root@CncLucZK test]# cat replace.txt
hello world!
123456abcdef
12345ABCDE

  • 当然,如果不想让行直接输出,可以用 -n 选项,再举个例子:
[root@CncLucZK test]# sed -n '1,3w replace.txt' demo2.txt
[root@CncLucZK test]# cat replace.txt
hello world!
123456abcdef
12345ABCDE

6.7.8 sed r 脚本命令
  • r 命令用于将一个独立文件的数据插入到当前数据流的指定位置,该命令的基本格式为:
[address]r filename
  • sed 命令会将 filename 文件中的内容插入到 address 指定行的后面,比如说:
[root@CncLucZK test]# cat replace.txt
hello world!
123456abcdef
12345ABCDE
[root@CncLucZK test]# sed '6r replace.txt' demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
hello world!
123456abcdef
12345ABCDE
  • 也可以将指定文件中的数据插入到数据流的末尾,可以使用 $ 地址符,例如:
[root@CncLucZK test]# sed '$r replace.txt' demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
hello world!
123456abcdef
12345ABCDE

6.7.9 sed q 退出脚本命令
  • q 命令的作用是使 sed 命令在第一次匹配任务结束后,退出 sed 程序,不再进行对后续数据的处理。
#第一个匹配3后停止
[root@CncLucZK test]# sed '/3/q'  demo2.txt
hello world!
123456abcdef
#shchu第3行后停止
[root@CncLucZK test]# sed '3q' demo2.txt
hello world!
123456abcdef
12345ABCDE

  • 使用 q 命令之后,sed 命令会在匹配到 number 1 时,将其替换成 number 0,然后直接退出。
[root@CncLucZK test]# sed '/3/{s/123/321/;q}'  demo2.txt
hello world!
321456abcdef
6.7.10 sed 脚本命令的寻址方式
  • 对各个脚本命令来说,address 用来表明该脚本命令作用到文本中的具体行。

  • 默认情况下,sed 命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须写明 address 部分,表示的方法有以下 2 种:

    1. 以数字形式指定行区间;
    2. 用文本模式指定具体行区间。
  • 该命令的基本格式为:

[address]脚本命令
[address]{多条脚本命令}
  • 以数字形式指定行区间:使用数字方式的行寻址时,可以用行在文本流中的行位置来引用。sed 会将文本流中的第一行编号为 1,然后继续按顺序为接下来的行分配行号。
  • 在脚本命令中,指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。这里举一个 sed 命令作用到指定行号的例子:
#打印demo2.txt文本文件内容
[root@CncLucZK test]# sed -n p demo2.txt
hello world!
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
#只打印第二行的内容
[root@CncLucZK test]# sed -n '2p' demo2.txt
123456abcdef
##打印第二至第三行的内容
[root@CncLucZK test]# sed -n '2,3p' demo2.txt
123456abcdef
12345ABCDE
#打印第二行之后的内容,用特殊地址——美元符($):
[root@CncLucZK test]# sed -n '2$p' demo2.txt
sed: -e expression #1, char 2: unknown command: `$'
[root@CncLucZK test]# sed -n '2,$p' demo2.txt
123456abcdef
12345ABCDE
aaaaaaaaaa
sssssssssss
qqqqqqqqq
  • 用文本模式指定行区间:sed 允许指定文本模式来过滤出命令要作用的行,格式如下:
/pattern/command

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

  • 打印匹配123的内容
[root@CncLucZK test]# sed -n '/123/p' demo2.txt
123456abcdef
12345ABCDE

  • 虽然使用固定文本模式能帮你过滤出特定的值,就跟上面这个用户名的例子一样,但其作用难免有限,因此,sed 允许在文本模式使用正则表达式指明作用的具体行。正则表达式允许创建高级文本模式匹配表达式来匹配各种数据。这些表达式结合了一系列通配符、特殊字符以及固定文本字符来生成能够匹配几乎任何形式文本的简练模式。关于正则表达式可以翻看正则表达式介绍使用
#仅打印有大写字母的内容
[root@CncLucZK test]# sed -n '/[A-Z]/p' demo2.txt
12345ABCDE
#打印有空白字符(换行、空格、tab制表符)的内容
[root@CncLucZK test]# sed -n '/\s/p' demo2.txt
hello world!
#打印abcde
[root@CncLucZK test]# sed -n '/[abcde]./p' demo2.txt
hello world!
123456abcdef
aaaaaaaaaa
#打印abc出现多次的内容
[root@CncLucZK test]# sed -n '/abc*/p' demo2.txt
123456abcdef

  • &用正则表达式匹配的内容进行替换
[root@CncLucZK test]# cat index.html
<html>
<title>tab</title>
<body>
h1 aa h1
h2 bb h2
h3 123 h3
</body>
</html>
#使用正则表示式给所有第一个的h1、h2、h3添加<>,给第二个h1、h2、h3添加</>
[root@CncLucZK test]# cat add.sh
/h[0-9]/{
    s//\<&\>/1
    s//\<\/&\>/2
}
[root@CncLucZK test]# sed -f add.sh index.html
<h1> aa </h1>
<h2> bb </h2>
<h3> 123 </h3>

参考文献:
Linux sed命令完全攻略(超级详细)

下一篇:Linux学习-15-Linux文本处理命令(awk、nl )

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123777.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!