0

我有以下类型的数据:

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 自动执行此操作...谢谢!

4

3 回答 3

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打印该行。

注意:p这是、P和之间n的区别N

  • n命令将打印出当前模式空间并读入下一行输入。
  • N命令不会打印出当前的模式空间。它读取下一行,但将一个新行字符与输入行本身一起附加到模式空间。
  • p命令打印整个模式空间。
  • P命令只打印模式空间的第一部分,直到 NEWLINE 字符。
于 2013-06-05T14:03:00.177 回答
4

一个稍微惯用的 awk 解决方案:

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

告诉它传入记录由一行--分隔,字段由换行符分隔,传出字段应由|标准换行符分隔,记录应由标准换行符分隔。$1 = $1强制重新格式化符合此。

如果文件不以 a 结尾--,最后你会得到一个额外|的,如果你需要避免这种情况,你可以稍微改变一下:

awk -F'\n' -vRS='\n--\n' -vOFS='|' '{if($NF==""){NF--}$1=$1;print}' test.in
于 2013-06-05T14:43:38.457 回答
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

更新

如果你添加一个额外的

--

在文件的末尾,它完全有效:

$ 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

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

于 2013-06-05T13:48:51.097 回答