使用 sed、awk 或其他在 Linux 命令行中从文本文件生成 csv
Generating csv from text file in Linux command line with sed, awk or other
我有一个包含数千行的文件,我想将其保存为 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
所以,现在所有内容都在一行中,并且“\”字符已被删除。
请注意每行的开头可能存在空格,因此在执行任何其他操作之前应先删除这些空格。
关于如何完成此任务的任何想法。 ?
提前致谢。
此致,
佩德罗
使用 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
基本上:
将一行读入模式space。
:line /\$/ {s/\$//; N; b line}
:如果模式 space 以 \
结尾,删除反斜杠,读取下一行并将其附加到模式 space,重复此步骤。
s/[[:space:]]+/,/g
: 将 1 个或多个白色 space 字符的每个大小写转换为单个逗号。
打印结果,换行回到开头
@Shawn 的回答已被 OP 接受,我不确定
如果我的回答值得发布,但请允许我这样做仅供参考。
如果 Perl
是您的选择,请尝试以下保留的脚本
parens 中的空格不替换为逗号:
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
中工作并保留空格
在 parens 之间不分界线。
我已经测试了大约。 10,000 行输入和执行时间
不到一秒。
希望这有帮助。
我有一个包含数千行的文件,我想将其保存为 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
所以,现在所有内容都在一行中,并且“\”字符已被删除。
请注意每行的开头可能存在空格,因此在执行任何其他操作之前应先删除这些空格。
关于如何完成此任务的任何想法。 ?
提前致谢。
此致, 佩德罗
使用 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
基本上:
将一行读入模式space。
:line /\$/ {s/\$//; N; b line}
:如果模式 space 以\
结尾,删除反斜杠,读取下一行并将其附加到模式 space,重复此步骤。s/[[:space:]]+/,/g
: 将 1 个或多个白色 space 字符的每个大小写转换为单个逗号。打印结果,换行回到开头
@Shawn 的回答已被 OP 接受,我不确定
如果我的回答值得发布,但请允许我这样做仅供参考。
如果 Perl
是您的选择,请尝试以下保留的脚本
parens 中的空格不替换为逗号:
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
中工作并保留空格 在 parens 之间不分界线。
我已经测试了大约。 10,000 行输入和执行时间
不到一秒。
希望这有帮助。