我有一个巨大的文本文件(500K行),其中一些行分为多行。我试图用分割线来获取记录,显示在一行中。当线被分割时,在下一行的开头之前有一个空行。现在,我循环遍历每一行,在开始时测试字符串(AAAA|
)以确定它是否是新行,然后与next连接。但这似乎需要花费很多时间,并想知道是否有更好的方法来做到这一点。此外,一些行分为多行,每个新记录以" AAAA |"开头。
输入文件:
AAAA|XXXX|YYYY|ZZZZ|532920-1*TYCO ELECTRONICS AMP#HDR4-2B-320-PSH2-A*CECO COMPONENT EQUIPMENT CO INC#
AAAA|XXXX|2342342|ADFADFS|A80386DX-33*INTEL CORP#
AAAA|SDFASF|234232322|saddfwq|ER412D-5A*TELEDYNE COMPONENTS#M39016/15-088L*QPL-39016#JMACD-5XL*HI-G INC#914S72101-10L*DRI RELAYS INC#M39016/15-082L*QPL-39016#3SBS1412A2*TYCO ELECTRONICS
CORP#
AAAA|XXXXXXX|5675423|XVASD|N74F132D-T*NXP SEMICONDUCTORS#74F132SC*FAIRCHILD SEMICONDUCTOR CORP#N74F132D*NXP SEMICONDUCTORS#MC74F132D*FREESCALE SEMICONDUCTOR INC#N74F132D,602*NXP SEMICONDU
CTORS#
AAAA|SDFASFSAS|23422|DFGAQWEWE|3SBS1411A2*TYCO ELECTRONICS CORP#914S70301-10L*DRI RELAYS INC#M39016/15-081L*QPL-39016#ER412D-26A*TELEDYNE COMPONENTS#JMACD-26XL*HI-G INC#M39016/15-087L*QPL
-39016#
AAAA|SFRQ3|34543534|NSGBSSDF|3SBS1223A2*TYCO ELECTRONICS CORP#914S60301-10L*DRI RELAYS INC#M39016/15-039L*QPL-39016#914S60301-09L*DRI RELAYS INC#M39016/15-051L*QPL-39016#ER412D-18A/S*TE
LEDYNE COMPONENTS#JMAPD-18XL*HI-G INC#
AAAA|ALSKFJ|1SFAE|ASLKFJSLKSAD|11163-164J*PHILIPS COMPONENTS#SEE_DRAWING_11163-164J*ROHM CO LTD#CF1/4L_164J*KOA SPEER ELECTRONICS INC#SEE_DRAWING_11163-164J*PHILIPS COMPONENTS#CF1/4L
U164J*KOA SPEER ELECTRONICS INC#CF1/4-160K-5%*KOA SPEER ELECTRONICS INC#11163-164J*ROHM CO LTD#131-00164-0053*HONEYWELL CROSS REFERENCE#CF1/4CT52A164J*KOA SPEER ELECTRONICS INC#CF1/4CT52R164J*KOA SPEE
R ELECTRONICS INC#||
AAAA|ASDFAA|1ASFSDAS|ASDFSA|MF 55 D 4323 F*KOA SPEER ELECTRONICS INC#2322156X4324*BC COMPONENTS INC#MF1/4DLT52R4323F*KOA SPEER ELECTRONICS INC#2322 156 X 4324*BC COMPONENTS INC#SFR55432K0
1%*BC COMPONENTS INC#CCF-55 4323 F*VISHAY DALE#CCF-554323F*VISHAY DALE#MF1/4DL_4323F*KOA SPEER ELECTRONICS INC#RN55D4323F*MILITARY SPECIFICATIONS#SFR55 432K0 1%*BC COMPONENTS INC#MF55D4323F*KOA SPEER
ELECTRONICS INC#||
答案 0 :(得分:3)
使用Perl保留空行:
perl -ne 'if (!/^$/) { chomp } else { print "\n" } print' input
使用Perl在连接后删除黑线:
perl -ne 'if (!/^$/) { chomp } print' input
使用GNU Sed(不处理posix模式中的最后一行):
sed '/^AAAA/{:l N;/\n./{s/\n//;bl}}' input
答案 1 :(得分:2)
假设只将最后一列拆分为多行:
awk -F"|" 'NF>1{if(x)print x;x=""}{x=x $0;}END{print x}' file
答案 2 :(得分:1)
算法的sed
版本“如果某行不以AAAA|
开头,只需与上一行连接:”:
sed -n '1x;2,${/^AAAA|/{x;s/\n//g;p};/^AAAA|/!H};${x;s/\n//g;p}' your_file.txt
与所有sed
脚本一样,需要一些解释:
-n
:不要在脚本末尾打印模式空间。1x
:记住保留空间中的第一行(交换保留和模式空间)。/^AAAA|/{x;s/\n//g;p}
:如果该行以新记录模式开头,则在保留空间中保存新行并返回保留空间的前一行(交换保留和模式空间),从前一行中删除新行记录并打印出来。/^AAAA|/!H
:如果该行不以新记录模式开头,请将其附加到保留空间中的上一行。${x;s/\n//g;p}
:对于最后一行,从保留空间取回数据,删除换行符并打印。答案 3 :(得分:0)
以下命令是否缓慢?
awk '!NF{print line; line=""}{line=line$0}' infile
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed ':a;$!N;/\nAAAA/{P;D};s/\n//;ta' file
答案 5 :(得分:0)
似乎每条记录应以井号结束。如果那是真的,那么:
awk '{printf("%s", $0)} /#$/ {print ""}' filename
答案 6 :(得分:0)
如果某行不以AAAA|
开头,只需与上一行连接:
awk 'NR == 1 { previous = $0 }
NR > 1 && $0 ~ "^AAAA[|]" { print previous; previous = $0 }
NR > 1 && $0 !~ "^AAAA[|]" { previous = previous $0 }
END { print previous }' your_file.txt
我们需要将|
放在[]
之间,因为它是扩展正则表达式的特殊字符。