Sed / Awk /剪切GNU将文本行转换为单行

时间:2013-06-05 13:45:35

标签: regex awk sed gnu gawk

我有以下类型的数据:

3869|Jennifer Smith
10413 NE 71st Street
Vancouver, WA
98662
360-944-9578
jsmith@yahoo.com|1234567890123456|03-2013|123
--
3875|Joan L Doe
422 1/2 14th Ave E
Seattle, WA
98112
206-322-7666
jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
--
3862|Dana Doe
24235 NE 7th Pl
Sammamish, WA
98074
425 868-2227
jsmith@hotmail.com|1234567890123456|03-2013|123
--
3890|John Smith
10470 SW 67th Ave
Tigard, OR
97223
5032205213
john.smith@gmail.com|1234567890123456|03-2013|123

我需要将其转换为:

3869|Jennifer Smith|10413 NE 71st Street|Vancouver, WA|98662|360-944-9578|jsmith@yahoo.com|1234567890123456|03-2013|123
3875|Joan L Doe|422 1/2 14th Ave E|Seattle, WA|98112|206-322-7666|jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
3862|Dana Doe|24235 NE 7th Pl|Sammamish, WA|98074|425 868-2227|jsmith@hotmail.com|1234567890123456|03-2013|123
3890|John Smith|10470 SW 67th Ave|Tigard, OR|97223|5032205213|john.smith@gmail.com|1234567890123456|03-2013|123

或更好:

3869|Jennifer Smith|10413 NE 71st Street|Vancouver|WA|98662|360-944-9578|jsmith@yahoo.com|1234567890123456|03-2013|123
3875|Joan L Doe|422 1/2 14th Ave E|Seattle|WA|98112|206-322-7666|jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
3862|Dana Doe|24235 NE 7th Pl|Sammamish|WA|98074|425 868-2227|jsmith@hotmail.com|1234567890123456|03-2013|123
3890|John Smith|10470 SW 67th Ave|Tigard|OR|97223|5032205213|john.smith@gmail.com|1234567890123456|03-2013|123

任何想法如何使用GNU sed,awk,cu或perl / python自动化这个... 谢谢!

3 个答案:

答案 0 :(得分:6)

使用sed

sed -n ':a;$!N;/--/!s/\n/|/g;ta;P' inputFile


$ sed -n ':a;$!N;/--/!s/\n/|/g;ta;P' temp 
3869|Jennifer Smith|10413 NE 71st Street|Vancouver, WA|98662|360-944-9578|jsmith@yahoo.com|1234567890123456|03-2013|123
3875|Joan L Doe|422 1/2 14th Ave E|Seattle, WA|98112|206-322-7666|jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
3862|Dana Doe|24235 NE 7th Pl|Sammamish, WA|98074|425 868-2227|jsmith@hotmail.com|1234567890123456|03-2013|123
3890|John Smith|10470 SW 67th Ave|Tigard, OR|97223|5032205213|john.smith@gmail.com|1234567890123456|03-2013|123

阐释:

  • :a创建标签a。
  • $!如果不是最后一行;做
  • N获取新行
  • /--/!如果行与此正则表达式不匹配;做
  • /s/\n/|/g用管道替换新行
  • 如果替换成功,则
  • ta分支回标签
  • P打印该行。

注意:以下是pPnN之间的区别。

  • n命令将打印出当前模式空间并读入 下一行输入。
  • N命令不会打印出来 当前的模式空间。它读入下一行,但附加一个新的 行字符以及输入行本身到模式空间。
  • p命令打印整个模式空间。
  • P命令 仅打印模式空间的第一部分,直到NEWLINE 字符。

答案 1 :(得分:4)

我认为这不是很好,但它几乎有效(缺少最后一行):

$ awk '{if (/^--/) {print a; a=""} else { a=a"|"$0}}' file
|3869|Jennifer Smith|10413 NE 71st Street|Vancouver, WA|98662|360-944-9578|jsmith@yahoo.com|1234567890123456|03-2013|123
|3875|Joan L Doe|422 1/2 14th Ave E|Seattle, WA|98112|206-322-7666|jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
|3862|Dana Doe|24235 NE 7th Pl|Sammamish, WA|98074|425 868-2227|jsmith@hotmail.com|1234567890123456|03-2013|123

更新

如果您添加额外的

--

在文件的末尾, completly 有效:

$ awk '{if (/^--/) {print a; a=""} else { a=a"|"$0}}' file
|3869|Jennifer Smith|10413 NE 71st Street|Vancouver, WA|98662|360-944-9578|jsmith@yahoo.com|1234567890123456|03-2013|123
|3875|Joan L Doe|422 1/2 14th Ave E|Seattle, WA|98112|206-322-7666|jldoe@comcast.net|1234-1234-1234-1234|03-2013|123
|3862|Dana Doe|24235 NE 7th Pl|Sammamish, WA|98074|425 868-2227|jsmith@hotmail.com|1234567890123456|03-2013|123
|3890|John Smith|10470 SW 67th Ave|Tigard, OR|97223|5032205213|john.smith@gmail.com|1234567890123456|03-2013|123

这是因为我的代码等待--打印正在缓冲的内容。

答案 2 :(得分:4)

稍微更惯用的awk解决方案:

awk -F'\n' -vRS='\n--\n' -vOFS='|' '{$1=$1;print}' test.in

告诉它传入记录由--组成的行分隔,字段用换行符分隔,出站字段应用|分隔,记录应用标准换行符分隔。 $1 = $1迫使重新格式化符合此要求。

如果文件没有以--结尾,您最后会得到额外的|,如果您需要避免这种情况,可以稍微更改一下:

awk -F'\n' -vRS='\n--\n' -vOFS='|' '{if($NF==""){NF--}$1=$1;print}' test.in