# cat test
1111111111
222222222
333333333
444444444
想当然的执行:
#sed 's/\n/\t/' test
1111111111
222222222
333333333
444444444
没有成功!
原因是sed读入一行,会去掉尾部换行符(但会保留$),存入pattern space,然后执行编辑命令,也可以顺序执行多个操作,中间用";"隔开,如:
#sed 's/1/x/1;s/1/b/2' test
x1b111111
222222222
333333333
444444444
第二个s操作,由于第1个1被第一个s操作替换成了x,第2个1变成了第1个1。
处理完毕,除非加了-n参数,把当前的pattern space打印出来,否则会在后边重新添加去掉的换行符,然后把pattern space内容给hold space,把pattern space清空。
在网上搜索了下,sed删除回车符的命令为:sed ':a;N;$!ba;s/\n/ /g' test
开始并不懂这条命令什么意思,之前也很少用,通过试验,终于有所了解,总结一下:
# sed ':loop;N;$!bloop;s/\n/\t/g' test
111111111 222222222 333333333 444444444
:loop(该循环名称可以自定义比如:a):表示sed进入循环,逐行将文本读入Pattern Space
N :这里就是循环里面所做的操作(当然我们也可以进行其他操作)N表示将文本的下一行追加到Pattern space,产生一个新行。
(在使用N的时候两行之间的$会取消)
$!bloop :循环结束标志,sed遇到最后行将退出循环否则返回loop
然后执行替换操作,s将回车(\n)替换成制表符(\t)
Pattern Space中的内容与执行的过程如下:
读取内容 是否为最后一行 Pattern Space
111111111 否 ^111111111$
222222222 否 ^11111111\n222222222$
333333333 否 ^111111111\n222222222\n333333333$
44444444 是 ^111111111\n222222222\n333333333\n44444444$
退出循环后, 执行s操作将\n替换成\t则为:^111111111\t222222222\t333333333\t44444444$
这是时候“\n”在pattern space中匹配序号在是依次排序为(1,2,3)
分别执行
#sed ':loop;N;$!bloop;s/\n/\t/1' test
111111111 222222222
333333333
444444444
# sed ':loop;N;$!bloop;s/\n/\t/2' test
111111111
222222222 333333333
444444444
# sed ':loop;N;$!bloop;s/\n/\t/3' test
111111111
222222222
333333333 444444444
了解pattern space里面的内容,就方便多了。执行:
sed ':loop;N;$!bloop;s/$/x/g' test
执行s操作将$替换成x则为:^111111111\n222222222\n333333333\n44444444x即:
111111111
222222222
333333333
444444444x
再看看,不对N进行循环操作,依次执行N;s操作
[root@dgtest ~]#sed 'N;s/\n/\t/' test
Pattern Space中的内容与执行的过程如下:
读入内容 Pattern Space
1111111111 ^1111111111$
222222222 ^1111111111\n222222222$
执行s操作将\n替换成\t则为: 111111111\t222222222$,清空!
333333333 ^33333333$
44444444 ^33333333\n44444444$
执行s操作将\n替换成\t则为: ^33333333\t44444444$
显然这个命令的输出结果为:
111111111 222222222
333333333 444444444
将test新增一行555555555
#sed 'N;s/^/x/' test
x111111111
222222222
x333333333
444444444
555555555
读取最后一行555555555的时候,不能再读一下行,退出了操作,没有在行首添加x
再比较下$!N与N的区别
# sed '$!N;s/^/x/' test
x111111111
222222222
x333333333
444444444
x555555555
$!N在执行N没有成功的时候,不会马上退出sed,而会去执行后续的操作,这里是在行首添加x
在vi中我们可以使用%s/\(^.*$\)\n\(^.*$\)/\1/删除偶数行,%s/\(^.*$\)\n\(^.*$\)/\2/删除奇数行
通过上面实验,我们也可以使用sed实现同样的操作。
# sed -n 'N;s/\(^.*\)\n\(.*$\)/\1/g;p' test
111111111
333333333
# sed -n 'N;s/\(^.*\)\n\(.*$\)/\2/g;p' test
222222222
444444444
但是如果是奇数行的话,最后一行将不显示,原因就是最后一行不能读取下一行,就退出了sed,没执行变更操作。