今天,朋友给我发来一段文本,他想让下面文本的第2,3行合并为一行,第4,5行合并为一行。
"id,name"
"abcd,d",",b,c,d
df"
"121,3","张三,
zhangsan"
他这个文本本来是excel的csv格式,但csv的数据在linux上以文本方式打开后,原来在excel一个单元格里的数据可能会分两行显示。如上面的"b,c,ddf"本来是在excel的一个单元格里面的,但你看在linux 以文本打开后,就显示成了两行。
我说那你用excel打开处理一下啊。他说数据太大,用excel打不开,问能不能在linux通过工具给处理一下。
我也在网上搜索了一下,最终用sed的N功能实现,对于sed我还是有了解的,但对于sed的N功能我也是第一次知道(看来sed和awk可我还有很多东西不知道的)。
原文本如下:
[root@node1 ~]# cat test
"id,name"
"abcd,d",",b,c,d
df"
"121,3","张三,
zhangsan"
利用sed的N+替换s功能得以实现:
[root@node1 ~]# sed '/[^"]$/{N;s/\n//}' test
"id,name"
"abcd,d",",b,c,ddf"
"121,3","张三,zhangsan
解释:
/[^"]$/ 这个是在sed里面运用了正则表达式。
[^"]表示引号"除外。
[^"]$表示引号"结尾的行除外。$是以什么结尾。
N表示把当前行和下一行合并。
\n是换行符的意思。
sed '/[^"]$/{N;s/\n//}' test 的解释就是在test文本中,将不是以引号"结尾的行和它的下一行合并成一行。
好了,相信你看了上面的解释,一定明白了这个命令行的意思了。
为了更好的解释sed的N功能,我们做以下几个实验,以加深理解。
[root@node1 ~]# cat test
"id,name"
"abcd,d",",b,c,d
df"
"121,3","张三,
zhangsan"
[root@node1 ~]# sed '$!N;s/\n/ /' test
"id,name" "abcd,d",",b,c,d
df" "121,3","张三,
zhangsan"
注:$是最后一行,!是不配匹的意思,N的意思就是把下一行追加到当前行尾。
$!N连起来的意思也就是一直向下N,直到最后一行不N。
下面详细说一下N命令:
如果没有下一行:
自动输出模式空间的内容(-n会阻止该输出),立即结束整个脚本。
如果有下一行:
在模式空间的内容后追加换行符(\n 0x0A),然后读入下一行追加到换行符之后。
控制传递给后续命令。如果有下一行,N后模式空间的内容应该是“模式空间原来的内容\n当前行的内容"。
我们再看下面的例子。
例子1:
[root@node1 ~]# sed 'N;s/\n/ /' test
"id,name" "abcd,d",",b,c,d
df" "121,3","张三,
zhangsan"
看到用$!N;s/\n/ /和N;s/\n/ /输入的结果一样。
例子2:
[root@node1 ~]# cat test
"id,name"
"abcd,d",",b,c,d
df"
"121,3","张三,
zhangsan"
[root@node1 ~]# sed '3N;s/\n/ /' test
"id,name"
"abcd,d",",b,c,d
df" "121,3","张三,
zhangsan"
上面的3N表示只合并第三行和第四行,其他行不合并。
好了,今天就到这了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28916011/viewspace-1484111/
,如需转载,请注明出处,否则将追究法律责任。