我有一个包含数千行的文件,我希望将其作为csv以便以后处理。
原始文件如下:
cc_1527 (ILDO_I173_net9 VSSA) capacitor_mis c=9.60713e-16
cc_1526 (VDD_MAIN Istartupcomp_I115_G7) capacitor_mis \
c=4.18106e-16
cc_1525 (VDD_MAIN Istartupcomp_I7_net025) capacitor_mis \
c=9.71462e-16
cc_1524 (VDD_MAIN Istartupcomp_I7_ST_net14) \
capacitor_mis c=4.6011e-17
cc_1523 (VDD_MAIN Istartupcomp_I7_ST_net15) \
capacitor_mis c=1.06215e-15
cc_1522 (VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_ST_net16) \
capacitor_mis c=1.37289e-15
cc_1521 (VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_I176_G4) capacitor_mis \
c=6.81758e-16
这里的问题是某些行继续到下一行,用符号“ \”表示。
原始文本前5行的最终csv格式应为:
cc_1527,(ILDO_I173_net9 VSSA),capacitor_mis c=9.60713e-16
cc_1526,(VDD_MAIN Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16
因此,现在所有内容仅在一行中,并且已删除“ \”字符。
请注意,每行的开头可能存在空格,因此在执行其他任何操作之前应将其修剪掉。
关于如何完成此操作的任何想法。 ?
谢谢。
最好的问候, 佩德罗
答案 0 :(得分:1)
使用sed的一些较晦涩的功能(它可以做的s///
以外):
$ sed -E ':line /\\$/ {s/\\$//; N; b line}; s/[[:space:]]+/,/g' demo.txt
cc_1527,(ILDO_I173_net9,VSSA),capacitor_mis,c=9.60713e-16
cc_1526,(VDD_MAIN,Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN,Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16
cc_1524,(VDD_MAIN,Istartupcomp_I7_ST_net14),capacitor_mis,c=4.6011e-17
cc_1523,(VDD_MAIN,Istartupcomp_I7_ST_net15),capacitor_mis,c=1.06215e-15
cc_1522,(VDD_MAIN,ILDO_LDO_core_Istartupcomp_I7_ST_net16),capacitor_mis,c=1.37289e-15
cc_1521,(VDD_MAIN,ILDO_LDO_core_Istartupcomp_I7_I176_G4),capacitor_mis,c=6.81758e-16
基本上:
在模式空间中读取一行。
:line /\\$/ {s/\\$//; N; b line}
:如果模式空间以\
结尾,请删除该反斜杠,阅读下一行并将其追加到模式空间,然后重复此步骤。
s/[[:space:]]+/,/g
:将每种情况下的1个或多个空格字符转换为单个逗号。
打印结果,并以新行返回到开头。
答案 1 :(得分:1)
@Shawn的答案已被OP接受,我不确定
如果我的答案值得发布,但请允许我仅供参考。
如果您选择Perl
,请尝试以下脚本,该脚本会保留
括号内的空格不能用逗号代替:
perl -0777 -ne '
s/\\\n//g;
foreach $line (split(/\n/)) {
while ($line =~ /(\([^)]+\))|(\S+)/g) {
push(@ary, $&);
}
print join(",", @ary), "\n";
@ary = ();
}
' input.txt
输出:
cc_1527,(ILDO_I173_net9 VSSA),capacitor_mis,c=9.60713e-16
cc_1526,(VDD_MAIN Istartupcomp_I115_G7),capacitor_mis,c=4.18106e-16
cc_1525,(VDD_MAIN Istartupcomp_I7_net025),capacitor_mis,c=9.71462e-16
cc_1524,(VDD_MAIN Istartupcomp_I7_ST_net14),capacitor_mis,c=4.6011e-17
cc_1523,(VDD_MAIN Istartupcomp_I7_ST_net15),capacitor_mis,c=1.06215e-15
cc_1522,(VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_ST_net16),capacitor_mis,c=1.37289e-15
cc_1521,(VDD_MAIN ILDO_LDO_core_Istartupcomp_I7_I176_G4),capacitor_mis,c=6.81758e-16
[工作原理]
-0777 -ne
选项告诉Perl
吞下所有行
进入Perl的默认变量$_
。s/\\\n//g;
通过合并行来删除结尾的反斜杠。split(/\n/)
再次将换行符拆分为行。/(\([^)]+\))|(\S+)/g
将是最重要的部分
将每一行划分为多个字段。字段模式定义为:
"substring surrounded by parens OR substring which does not include whitespaces."
在FPAT
中用作awk
,并保留空格
在两个括号之间,而不必在其上划分线。我测试了大约10,000行输入和执行时间
不到一秒钟。
希望这会有所帮助。