shell的三剑客sed
Posted 他和晚风一样温柔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell的三剑客sed相关的知识,希望对你有一定的参考价值。
sed编辑器
- sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
- sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。
sed的工作程
- 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
- 执行:默认情况下,所有的sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed 命令将会在所有的行上依次执行。
- 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:
- 在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
- 默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。
命令格式:
sed -e'操作'文件1 文件2 ...
sed -n -e'操作·文件1 文件2 ... #把显示的作用关掉
sed -f 脚本文件 文件1 文件2.... #-f指读取脚本文件命令执行其他文件
sed -i -e'操作·文件1 文件2... #对文件可以直接修改
例如
sed -e 'n{
操作1
操作2
...
}'文件1 文件2 ... #可以执行很多文件
常用选项:
- -e:表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用
- -f:表示用指定的脚本文件来处理输入的文本文件。
- -h:显示帮助。
- -n、–quiet 或silent:禁止sed编辑器输出,但可以与p命令一起使用完成输出。
- -i:直接修改目标文本文件。
常用操作:
- s:替换,替换指定字符。
- d:删除,删除选定的行。
- a:增加,在当前行下面增加一行指定内容。
- i:插入,在选定行上面插入一行指定内容。
- c:替换,将选定行替换为指定内容。
- y:字符转换,转换前后的字符长度必须相同。
- p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用。
- l(小写L):打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\\t)
sed -n -e 'p' 1.txt #使用-n解决这个问题,要注意n要在e前面,n和p操作要结合使用
sed '=' sedfile.txt #行号在内容上面
sed -n -e '=;p' sedfile.tx #先追加行号再打印
注:‘;’表示前后顺序的
sed -n -e 'p' -n -e '=' sedfile.txt #先打印内容,再输出行号
sed -n -e 'l' sedfile.txt #扩展:输出内容并展示不可打印字符
注:多条命令使用-e不能去掉
使用地址功能
sed编辑器有两种寻址方式
- 以数字形式表示行区间
- 用文本模式来过滤出行
ps:数字与文本都要写在操作符的左边,文本需要用 // 解释
n 表示跳到下一行
行的范围 与操作符一起使用后,操作符需要加在 ${} 中
用文本模式来过滤出行
- 文本需要写在 // 中, /文本/操作符
- 区分大小写
- | 等符号需要加转义符 \\
sed -n -e '/root/p' /etc/passwd
sed -n -e '/bash$/p' /etc/passwd
sed -n -e '/ftp\\|root/p' /etc/passwd
sed -n '/root/p' sedfile.txt
#sed查找文本 区分大小写
使用 -r 选项表示 操作中支持使用正则表达式,表达式要用 // 符号进行解释。
#正则表达式表示打印 以ro开头,o至少出现一次的字符串所在的行
sed -n -r '/ro{1,}t/p' /etc/passwd
删除
- sed 是把文件读取到缓冲区中,在缓冲区中进行的删除,并不修改原文件的内容
- 删除 操作符d 不能与 -n 选项一起使用,不然什么都不会输出
sed 'd' sedfile.txt #全删
sed '3d' sedfile.txt #删除第三行
'3,6d' 删3到6行 '3,$d' 删三到末尾所有行
sed -r '/^$/d' sedfile.txt #使用正则表达式 删除空行
删除空行另外两种方法:
cat sedfile.txt | tr -s '\\n'
cat sedfile.txt | grep -v "^$"
sed -r '/nologin$/d' /etc/passwd
sed -r '/nologin$/!d' /etc/passwd #!取反操作
#删除从。。到。。。之间的行,继续往下找,指直到文件读取完
sed '/1/,/3/d' numsedfile.txt
替换(常用)
格式:行范围 s/旧字符串/新字符串/替换标记
- 行范围 与后面用空格隔开
- 行范围如果是正则表达式,用 // 解释
4种替换标记:
数字:表明新字符串将替换【第几处匹配的地方】
g:表明新字符串将会替换【所有匹配的地方】
p:打印与替换命令匹配的行,与 -n 一起使用
w 文件:将替换的结果写到文件中
行范围可以用 1,4 或 1+3 等表示
直接替换
sed -n -e 's/root//gp' /etc/passwd #将所有的(g) root 替换成空
sed -n -e 's/root//p' /etc/passwd #将第一个 root 替换成空
sed -n -e 's/root//2p' /etc/passwd #将第二个 root 替换成空
#将文件 /etc/passwd 第1到20行的 开头替换成#号
sed '1,20 s/^/#/' /etc/passwd
#将root开头的行 结尾替换为#
sed '/^root/ s/$/#/' /etc/passwd
#替换标记为空
使用指定的脚本文件来处理输入的文本文件
格式 : -f 脚本文件file
其实就是把多条 sed 操作语句放到文件中,这样能够一次执行多条语句,不然只能一条一条的执行下去。
测试:
新增文件 script.sed ,添加内容:
/^root/ s/^/#/
/bash$/ s/\\/bin\\/bash/\\/sbin\\/nologin/
#//之间的符号要使用转义符
执行:能够根据scripr.sed文件中的语句对 /etc/passwd 进行多次操作
把 sed 执行结果写到文件中
#把 /etc/passwd 中第1到5行写到文件out.txt 中
sed '1,5w out.txt' /etc/passwd
#把 /etc/passwd 中第1到5行,的开头加上# 后 写到文件out.txt 中
sed '1,5 s/^/#/w out.txt' /etc/passwd
修改字符串分隔符
修改分隔符的好处是不需要再给表达式的重名如 / 再加上转义符\\了
#把/bin/bash 替换为 /bin/csh
sed -n 's/\\/bin\\/bash/\\/bin\\/csh/p' /etc/passwd
#用!作为替换的分隔符,等同于/,不要再写转义符了
sed -n 's!/bin/bash!/bin/csh!p' /etc/passwd
#test.txt中有文件 94599
#将94599替换为9893
sed 's9\\945\\9\\99\\98\\939g' test.txt
#sed -i's9\\945\\9\\99\\98\\939g' test.txt 会更改test.txt 文件中的值。
#因为分隔符9 与表达式的内容9重名,所以表达式中的9需要加转义符\\9 来表示 9。
#因此可以这样看 s9 \\945\\9\\9 9 \\98\\93 9g
#用9做分隔符其实不好,重名了,只是为了演示用法
插入
a: 增加,在当前行下面增加一行指定内容。
i: 插入,在选定行上面插入一行指定内容。
c: 替换,将选定行替换为指定内容。
y: 字符转换,转换前后的字符长度必须相同。
r: 跟文件名,注入文件中的内容
例子:
#将含有字符串45的行,整体替换为 ABC
sed '/45/c ABC' numedfile.txt
#将含有字符串45的行,字符45转换AB
sed '/45/ y/45/AB/' numsedfile.txt
#将含有字符串45的行,字符145转换ABC,字符45转换BC
sed '/45/ y/145/ABC/' numsedfile.txt
替换
添加:
#在1-3行每一行上面各添加一行ABCD
sed '1,3i ABCD' numsedfile.txt
#在1-3行每一行下面各添加一行ABCD
sed '1,3a ABCD' numsedfile.txt
从文件中导入数据
#在numsedfile.txt 的第三行后面增加 /root/test.txt 文件中的内容
sed '3r /root/test.txt' numsedfile.txt
#将包含root的行 剪切到末尾,H表示复制到剪切板,G表示粘贴到指定行后
sed '/root/{H;d};$G' /etc/passwd
#将1、2行 复制到 3和4行的下面
sed '1,2H;3,4G' /etc/passwd
先H复制后,用分号; 与G黏贴分开,表示 有先后顺序
去除黏贴后产生的空行
sed '1,2H;3,4G' /etc/passwd | sed '^$d'
使用sed修改文件
sed 的插入等操作符都是在缓冲区(模式空间)中 执行和显示的,并不会修改原文件内容
如果想用 sed 修改原文件,可以用-选项 ** -i 直接修改目标文本文件**
以上是关于shell的三剑客sed的主要内容,如果未能解决你的问题,请参考以下文章