transpose/unfold 行内嵌套数据的命令行

Command line to transpose/unfold nested data within rows

用分隔数据展开一行的聪明而简洁的方法是什么?我可以想象一个在 ruby 或 perl 中逐行处理的小脚本,但这可以优雅地完成吗?

来自这里:

 alpha @ ä | b | ç @ 1.1 | 2.1 | 3.1
 beta @ d | é | f @ 4.2 | 5.2 | 6.2

进入这个:

 alpha @ ä @ 1.1
 alpha @ b @ 2.1
 alpha @ ç @ 3.1
 beta @ d @ 4.2
 beta @ é @ 5.2
 beta @ f @ 6.2

总是有 3 个主要列,第 1 列总是内容,第 2 列和第 3 列有不可预测的非空内容。例如,我可以在一行中有 50 个项目。第 1 列和第 2 列可能有 [^a-zA-Z](即 unicode)。只要简洁,perl 或 ruby 中的一行就可以了。 sed 总是受欢迎的,但我认为这超出了 sed 的能力范围。

我正在使用 MacOS。

我的实际数据的格式和分隔符略有不同;例如,我使用制表符而不是 @,并且没有空格,但是 @ 在这里更容易阅读。让我的数据符合这个或类似的语法对我来说是微不足道的。

$ awk -F@ '{n=split(,a,"|"); split(,b,"|"); for (i=1;i<=n;i++)print  "@" a[i] "@" b[i];}' file
alpha @ ä @ 1.1 
alpha @ b @ 2.1 
alpha @ ç @ 3.1
beta @ d @ 4.2 
beta @ é @ 5.2 
beta @ f @ 6.2

以上是使用 GNU awk 测试的。

工作原理

  • -F@

    将字段分隔符设置为 @。如果您更喜欢制表符,只需将 @ 替换为 "\t"

  • {n=split(,a,"|"); split(,b,"|")

    用分隔符|拆分第二列和第三列,并将结果分别存储到数组ab中。数组 a 的长度保存在变量 n.

  • for (i=1;i<=n;i++)print "@" a[i] "@" b[i]

    打印输出。

$ awk -F'[@|]' -v OFS='@' '{n=(NF-1)/2; for (i=2;i<=(n+1);i++) print , $i, $(i+n)}' file
alpha @ ä @ 1.1
alpha @ b @ 2.1
alpha @ ç @ 3.1
beta @ d @ 4.2
beta @ é @ 5.2
beta @ f @ 6.2