将列标准化为从管道分隔的文本流中的行

时间:2014-06-06 14:14:44

标签: sql perl bash awk sed

我正在寻找一个简洁的命令行工具/脚本来获取另一个命令的输出,并将文本转换为规范化数据集以导入数据库。

我的输入流目前看起来像这样:

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

完成了这项工作

2 个答案:

答案 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]);
}
相关问题