awk与sed:一个关于多行处理的例子

前几天在CSDN上看到一个帖子http://bbs.csdn.net/topics/390848841,楼主贴了下面的问题:

  1. 例:
  2. 12345
  3. 67890
  4. 1234567890
  5. 123
  6. 4567890
  7. 如何能把上面数据转换成
  8. 1234567890
  9. 1234567890
  10. 1234567890

看了几位网友的回复,觉得还是挺有意思,也收获了一些知识,因为部分网友只给出了解决方法,没有解释下,我根据自己的理解,对几个答案解释下(不一定准确,错误之处请指正)

我认为错的答案

1    首先楼主给出了一个他说调试不出来的答案:

  1. sed ‘s/(?!90)\n//g‘

?!应该是非pattern结尾的意思,这个答案应该是说把非90结尾的行的换行符换位空。

这个答案应该是不可行的。sed默认单行模式,一次处理一行,运行时发现,就算我们把换行符去掉了,sed命令结束后,还是将它当成完整的一行输出(也就是说,应该是自动又加上换行符了)

2.    有一位网友,觉得其他答案太复杂,给出了下面的方法

  1. sed ‘N;s/\n//g’

这个答案使用了sed的多行模式,但应该是无法实现楼主的目的的。我们看运行结果“

  1. [email protected]:~/Windeal/shell$ sed ‘N;s/\n//g‘ a.txt
  2. 1234567890
  3. 1234567890123
  4. 4567890

可以看出,sed 的N命令把第二行接到第一行后面,把第四行接到第三行后面,没有考虑到我们目标中:只有非90结尾的才把下一行附加上来。所以第四行的123被附加到第三行1234567890而出现了错误的结果。

我认为对的答案

再来看两个我认为对的答案:

1.

  1. sed -e ‘/^/{:loop /90$/!{N;b loop};s/\n//g}‘ test.txt > t2.txt
  2. 改一下好理解一点就是
  3. sed ‘{:myloop /90$/!{N;b myloop};s/\n//g}‘ a.txt

/^/的意思我没弄明白,应该是匹配每一行吧

在该命令中,myloop是一个自定义的标签。类似程序语言中goto用的标签。 N表示多行模式,b表示分支(相当于goto)

这样就好理解了,sed会读取一行内容,如果这一行不是以90结尾,/90$/! 就为真,进入{N;b myloop}。N就进入了多行模式,把下一行附加上来,然后进入分支b
myloop,在判断是不是以90结尾,这样反复读取,直到读到以90结尾的行。接下来模式空间的读取工作已经完成,进入下一个命令,替换,s/\n//g?这个命令把当前模式空间的换行符都转换为空,也就是拼接成一行。

如此,我们就完成了我们要的目的。

2.

  1. awk ‘{if($0~/90$/){print}else{printf("%s",$0)}}‘ a.txt

这个答案读取了一行的所以字段(实际上就1个字段,) 用$0表示,然后if($0~/90$/)判断是不是以90结尾。

如果以90结尾,就输出当前行数据。

如果不是,就格式化输入当前航的字符串

注意print和printf的区别

时间: 2024-10-11 21:47:04

awk与sed:一个关于多行处理的例子的相关文章

awk与sed:关于多行的样本

几天前CSDN看到一个帖子http://bbs.csdn.net/topics/390848841,楼主贴了以下的问题: 例: 12345 67890 1234567890 123 4567890 怎样能把上面数据转换成 1234567890 1234567890 1234567890 看了几位网友的回复.认为还是挺有意思,也收获了一些知识,由于部分网友仅仅给出了解决方法,没有解释下.我依据自己的理解,对几个答案解释下(不一定准确,错误之处请指正) 我觉得错的答案 1    首先楼主给出了一个他

利用多核CPU来加速Linux命令 — awk、sed、bzip2、grep、wc

你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作--一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如 grep, bzip2, wc, awk, sed等等,都是单线程的,只能使用一个CPU内核.借用卡通人物Cartman的话,"如何我能使用这些内核"?要想让Linux命令使用所有的CPU内核,我们需要用到GNU Parallel命令,它让我们所有的CPU内核在单机内做神奇的map-reduce操作

使用awk和sed获取文件奇偶数行的方法总结

测试文件test.file [root@localhost ~]# cat test.file 111111111111111 222222222222222 333333333333333 444444444444444 555555555555555 666666666666666 777777777777777 888888888888888 999999999999999 1010101010101010 1) 打印奇数行的方法 [root@localhost ~]# sed -n '1

用awk、sed打印奇数行或偶数行

这里只介绍最简单的方法 sed实现一:奇数行 sed -n 'p;n' file偶数行 sed -n 'n;p' file 这个可能比较难理解,举个网上的例子: 例,从aaa文件中取出偶数行cat aaa This is 1    This is 2    This is 3    This is 4    This is 5 sed -n 'n;p' aaa         //-n表示取消默认输出 This is 2    This is 4 注 释:sed读取This is 1,执行n命令

sed 删除最后几行 和删除指定行 awk使用

sed 删除最后几行 和删除指定行 转载原文链接:http://blog.51cto.com/lspgyy/1305489 sed 想删除文件中的指定行,是可以用行号指定也可以用RE来匹配的. 删除指定的行[可以指定行号删除.匹配字符串来删除] [[email protected] ~]# cat -n seq.txt 1 ok i will help you 2 understand sed usage 3 how to use it 4 and we should use it in vie

linux awk用法(主要为命令行)

简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK

Linux字符串截取和处理命令 cut、printf、awk、sed、sort、wc

1. cut [选项] 文件名 -f  列号 #提取第几列(分隔符默认为\t) -d  分隔符 #指定分隔符 例如:cut -f 2 a.txt #截取文件a.txt内容的第二列(列号从1开始) cut -f 2,4 a.txt #截取文件a.txt内容的第二列和第四列 cut -d  ":"  -f 1,3 /etc/passwd #截取文件passwd文件的第1列和第三列,以:分割取其中的第一列和第三列 2. printf '输出类型 输出格式'  输出内容 输出类型: %ns 输

awk和sed (十二)

[教程主题]:4.awk和sed [主要内容] [1]awk AWK是贝尔实验室1977年搞出来的文本出现神器.之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符.要学AWK,就得提一提AWK的一本相当经典的书<The AWK Programming Language>,它在豆瓣上的评分是9.4分!在亚马逊上居然卖1022.30元. Awk和sed 第二版 我从netstat命令中

【文本处理】awk、sed使用 - 更新中

一.正则介绍 基本元字符(基本正则表达式): 字符匹配: .  匹配换行符之外的任意一个字符 [] 字符组元字符,元字符在[]内,会失去特殊意义不用转义 [^] 除开字符组中的字符 次数匹配: *  匹配前面字符零次或多次 \?  零次或一次 \{m,n\}  至少m次,至多n次 \{m,\}   m次 锚定符: \<,\b  词首锚定 \>,\b  词尾锚定 ^    行的开头 $    行的结尾 ^$   空行 .*   任意字符串 分组: \(\)     \1,\2   前向引用,\1