我正在寻找一个简洁的命令行工具/脚本来获取另一个命令的输出,并将文本转换为规范化数据集以导入数据库。
我的输入流目前看起来像这样:
timestamp|identifier|column1|column2|...|column n
(同时代表n个观察结果,对于相同的标识符(人))
我想获取前两个字段,然后将它们添加到column1-n以生成如下输出:
timestamp|identifier|column1
timestamp|identifier|column2
timestamp|identifier|column3
...
timestamp|identifier|column n
sed的? AWK? Perl的?或者,将这些数据按原样加载到数据库表中会更好,然后使用某种转换脚本存储过程吗?我相信我之前在SQL Server中使用PIVOT
完成了这项工作答案 0 :(得分:5)
这可以做到:
$ awk 'BEGIN{FS=OFS="|"} {for (i=3; i<=NF; i++) print $1, $2, $i}' file
timestamp|identifier|column1
timestamp|identifier|column2
timestamp|identifier|...
timestamp|identifier|column n
BEGIN{FS=OFS="|"}
将输入和输出字段分隔符设置为|
。for (i=3; i<=NF; i++) print $1, $2, $i
循环遍历所有字段,因为第三次打印第一列,第二列+当前字段。答案 1 :(得分:5)
perl -F'\|' -lane 'print join "|", @F[0,1],$_ for @F[2..$#F]' file
输出
timestamp|identifier|column1
timestamp|identifier|column2
timestamp|identifier|column n
说明:
-F'\|'
是隐式拆分的分隔符,它应该被转义,因为它是正则表达式
-l
自动选择换行符,并在打印时添加一个
-a
自动拆分为@F
数组
-n
添加了隐式while(<>)
循环
或者让perl说话,
perl -MO=Deparse -F'\|' -lane 'print join "|", @F[0,1],$_ for @F[2..$#F]'
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
our(@F) = split(/\|/, $_, 0);
print join('|', @F[0, 1], $_) foreach (@F[2 .. $#F]);
}