linux中sed删除内容,sed命令_Linuxsed命令:替换、删除、更
新⽂件中的内容
sed 是 editor 的缩写,中⽂称之为“流编辑器”。
sed 命令是⼀个⾯向⾏处理的⼯具,它以“⾏”为处理单位,针对每⼀⾏进⾏处理,处理后的结果会输出到标准输出(STDOUT)。你会发现sed 命令是很懂礼貌的⼀个命令,它不会对读取的⽂件做任何贸然的修改,⽽是将内容都输出到标准输出中。
我们来看看 sed 的命令格式:
sed command file
command 部分:针对每⾏的内容所要进⾏的处理(这部分很重要很重要)。
file 部分:要处理的⽂件,如果忽略 file 参数,则 sed 会把标准输⼊作为处理对象。
sed 的⼯作原理是什么
刚才我们说了,sed 命令是⾯向“⾏”进⾏处理的,每⼀次处理⼀⾏内容。处理时,sed 会把要处理的⾏存
储在缓冲区中,接着⽤ sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下⼀⾏,这样不断重复,直到⽂件末尾。这个缓冲区被称为“模式空间”(pattern space)。
如前⾯所说,在这个处理过程中,sed 命令并不会对⽂件本⾝进⾏任何更改。
我们来⼀起看⼀个最最简单的 sed 命令的例⼦,让⼤家对它有个感性的认识。
#我们先来看看原⽂件的内容
[roc@roclinux ~]$
test 1
test2
testtest
XtestX
BBtest
#我们想⽤sed命令来删除⽂件中带字符“2”的⾏
[roc@roclinux ~]$ sed '/2/d'
test 1
testtest
XtestX
BBtest
此例⼦是利⽤ sed 来删除 ⽂件中含有字符“2”的⾏。看到了吧,例⼦很简单,这个命令的 command 部分是/2/d,⽽且它是⽤单引号括起来的。你也⼀定要学着这样做,⽤到 sed,别忘了⽤单引号将 command 部分括起来。
/2/d中的 d 表⽰删除,意思是说,只要某⾏内容中含有字符 2,就删掉这⼀⾏。(sed 所谓的删除都是在模式空间中执⾏的,不会真正改动 原⽂件。)
想⽤ sed 命令实现 cut 命令的效果
假如我们想实现类似于 cut-d:-f 1/etc/passwd 的效果,也就是以冒号为间隔符提取第 1 个域,⽤ sed 命令应该怎么操作呢?
#先来⼀起看看/etc/passwd⽂件的内容
[roc@roclinux ~]$ head -n 5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#我们这回⽤sed命令来提取⽂件中每⾏的第⼀个域, 间隔符是冒号
[roc@roclinux ~]$ head -n 5 /etc/passwd|sed 's/:.*$//'
root
bin
daemon
adm
lp
看到了吧,我们将 command 部分指定成了's/:.*$//',表⽰我们要把每⼀⾏的第⼀个冒号到结尾的部分都清空,这样留下的便是第⼀个冒号前的内容啦。
sed 都有哪些好⽤的选项
说到 sed 命令的选项,就不得不提-n选项,想把这个选项介绍清楚,还是要费⼀些脑⼦和笔墨的。
前⾯提到,sed 会将模式空间⾥的⾏经过处理后输出到标准输出,这是默认的处理⽅式。也就是说,除⾮你使⽤“d”来删除此⾏,否则经过“模式空间”处理的⾏都是会被输出到标准输出(屏幕)上的。我们⼀起来看下⾯的例⼦:
#还是先来看看原⽂件的内容
[roc@roclinux ~]$
1
2
3
4
5
#仔细看, 输出中出现了两个“4”
[roc@roclinux ~]$ sed ‘/4/p’
1
2
3
4
4
5
看,所有的原始⽂件内容都被输出来了,⽽且含有字符4的⾏被输出了两遍。
但这就是 sed 命令的⼯作原理,它会不问青红皂⽩地把经过处理的⾏先输出出来,然后再执⾏后⾯的动作。(在这⾥我们设定了 p,表⽰打印此⾏。)这明显不符合我们的初衷,我们只是想让 sed 命令到含有 4 的⾏再输出。
这时候,不妨加上-n选项试⼀试,你会发现,结果变得如你所愿了。
[roc@roclinux ~]$ sed -n '/4/p'
4
-n选项会很严肃地警告 sed 命令:除⾮是明确表明要输出的⾏,否则不要给我胡乱输出。-n选项经常和 p 配合使⽤,其含义就是,输出那些匹配的⾏。
command 部分花样很多
还记得我们在前⾯介绍过的,sed 命令的命令格式是这样的:
$ sed command file
其中,command 部分是 sed 命令的精髓,对 command 部分的掌握程度决定了你是不是 sed ⾼⼿。
command 部分可以分为两块知识:⼀块是范围设定,⼀块是动作处理。
范围设定,可以采⽤两种不同的⽅式来表达:
指定⾏数:⽐如‘3,5’表⽰第 3、第 4 和第 5⾏;⽽‘5,$’表⽰第 5 ⾏⾄⽂件最后⼀⾏。
模式匹配:⽐如/^[^dD]/表⽰匹配⾏⾸不是以 d 或 D 开头的⾏。
⽽动作处理部分,会提供很丰富的动作供你选择,下⾯就来介绍⼏个最常⽤的动作吧:
d:表⽰删除⾏。
p:打印该⾏。
r:读取指定⽂件的内容。
w:写⼊指定⽂件。
a:在下⾯插⼊新⾏新内容。
展⽰ sed 实⼒的时候到了
事实胜于雄辩,我们打算通过四个例⼦,让⼤家感受到 sed 命令真的是⼀位“实⼒派”选⼿。
第⼀个例⼦,我们来显⽰ test ⽂件的第 10 ⾏到第 20 ⾏的内容:
#我们采⽤了刚才提到的指定⾏区间的⽅法
[roc@roclinux ~]$ sed -n '10,20p' test
第⼆个例⼦,我们尝试将所有以 d 或 D 开头的⾏⾥的所有⼩写 x 字符变为⼤写 X 字符:
[roc@roclinux ~]$ sed '/^[dD]/s/x/X/g' test
这个⽤法值得⼀讲,我们在 command 部分采⽤了 /AA/s/BB/CC/g 的语法格式,这表⽰我们要匹配到⽂件中带有 AA 的⾏,并且将这些⾏中所有的 BB 替换成 CC。
第三个例⼦,我们要删除每⾏最后的两个字符:
#点号表⽰⼀个单个字符, 两个点号就表⽰两个单个字符
[roc@roclinux ~]$ sed 's/..$//' test
有⼈可能会问,⽤ sed‘/..$/d’test 为什么不⾏呢,d 不是表⽰删除么?⽤ d 是不⾏的,这是因为 d 表⽰删除整⾏内容,⽽⾮字符。
'/..$/d'表⽰的是匹配所有末尾含有两个字符的⾏,然后删除这⼀整⾏内容,显然这和我们的初衷是相悖的。
第四个例⼦,我们希望删除每⼀⾏的前两个字符:
[roc@roclinux ~]$ sed 's/..//' test
通过这四个例⼦,相信⼤家对 sed 命令的最常见⽤法已经有了很直观的认识了,不妨在⾃⼰的实际⼯作中把这些知识⽤起来吧。
& 符号的妙⽤
我们仍然通过⼀个场景来讲解这个知识点。
#按照惯例, 先展⽰⽂件的内容
[roc@roclinux ~]$
Beijing
London
#我们使⽤到了&符号, ⼤家试着猜⼀猜它的作⽤
[roc@roclinux ~]$ sed 's/B.*/&2008/'
Beijing2008
London
不卖关⼦,答案揭晓啦,这个命令的作⽤是将包含‘B.*’的字符串后⾯加上 2008 四个字符。这个命令中我们⽤到了 & 字符,在 sed 命令中,它表⽰的是“之前被匹配的部分”,在我们的例⼦中当然就是 Beijing 啦!
我们再通过⼀个例⼦强化⼀下⼤家对&符号的理解:
#这个例⼦或许更易理解
[roc@roclinux 20160229]$ sed 's/Bei/&2008/'
Bei2008jing
London
sed 中的括号有深意
在 sed 命令中,其实⼩括号‘()’也是有深意的。我们开门见⼭,通过⼀个例⼦,让⼤家见识⼀下⼩括号的威⼒:
[roc@roclinux ~]$ echo "hello world" | sed 's/.*/world \1/'
world hello
我们看到,原本是“hello world”,经过 sed 的处理,输出变成了“world hello”。
这个例⼦中就⽤到了⼩括号的知识,我们称之为“sed 的预存储技术”,也就是命令中被“(”和“)”括起来的内容会被依次暂存起来,存储到 \1、\2…⾥⾯。这样你就可以使⽤‘\N’形式来调⽤这些预存储的内容了。
来继续看⼀个例⼦,我们希望只在每⾏的第⼀个和最后⼀个 Beijing 后⾯加上 2008 字符串,⾔下之意就是,除了每⾏的第⼀个和最后⼀个2008 之外,这⼀⾏中间出现的 Beijing 后⾯就不要加 2008 啦。这个需求,真的是很复杂很个性化,但 sed 命令仍然可以很好地满⾜:
#先看下⽂件内容, 第⼀⾏中出现了4个Beijing
[roc@roclinux ~]$
Beijing Beijing Beijing Beijing
London London London London
#效果实现啦, 可是, 命令真的好复杂
[roc@roclinux ~]$ sed 's//\12008\2\32008/'
Beijing2008 Beijing Beijing Beijing2008
London London London London
这个命令确实⾜够复杂,⽤流⾏的语⾔说就是“⾜够虐⼼”。这个例⼦中我们再次使⽤了预存储技术,存储了三项内容,分别代表第⼀个Beijing、中间的内容、最后的 Beijing。⽽针对\1和\3,我们在其后⾯追加了 2008 这个字符串。
更聪明的定位⾏范围
实践是学习知识最好的⽅法,相信⼤家看了这个例⼦后,就明⽩如何更好地定位⾏范围了:
#⽂件内容展⽰⼀下
[roc@roclinux ~]$
linux查看当前文件夹内容Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
Beijing 2007
#我们想展⽰匹配了2005的⾏和2007的⾏之间的内容
[roc@roclinux ~]$ sed -n ‘/2005/,/2007/p’
Beijing 2005
Beijing 2006
Beijing 2007
我们使⽤ /2005/ 来匹配⾏范围的⾸⾏,⽤ /2008/ 来匹配⾏范围的尾⾏。可以看到,在匹配尾⾏时,只要遇到第⼀个符合要求的⾏,就会停⽌,⽽不会再继续向后匹配了。所以,sed 命令只是匹配到了第⼀个 2007,并没有匹配到第⼆个 2007。
⽤ -e 选项来设置多个 command
还记得 command 部分吧,现在有⼀个好消息要告诉你,那就是 sed 命令可以包含不只⼀个 comman
d。如果要包含多个 command,只需在每个 command 前⾯分别加上⼀个-e选项即可。
#我们通过2个-e选项设置了两个command
[roc@roclinux ~]$ sed -n -e ‘1,2p’ -e ‘4p’
Beijing 2003
Beijing 2004
Beijing 2006
有⼀个地⽅值得⼤家注意,那就是-e选项的后⾯要⽴即接 command 内容,不允许再夹杂其他选项。
-e选项⽀持设置多个 command,这原本是⼀件好事情,让我们可以更⽅便地实现⼀些替换效果。但是,这也给我们带来了幸福的烦恼,假如我们设定了很多个 command,那它们的执⾏顺序是怎样的呢?
如果这⼀点不搞明⽩,-e选项带来的或许只有混乱⽽⾮便捷。我们来⼀起看看下⾯的例⼦:
#先看看⽂件的内容
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论