![需要有关制作多列的帮助](https://linux22.com/image/227129/%E9%9C%80%E8%A6%81%E6%9C%89%E5%85%B3%E5%88%B6%E4%BD%9C%E5%A4%9A%E5%88%97%E7%9A%84%E5%B8%AE%E5%8A%A9.png)
我需要将数据转换为多列。输入数据:
a1 n1
a2 n2
a3 n3
. .
. .
. .
an nn
a1 m1
a2 m2
a3 m3
. .
. .
. .
an mn
a1 x1
a2 x2
a3 x3
. .
. .
. .
an xn
a1 y1
a2 y2
a3 y3
. .
. .
. .
an yn
a1 z1
a2 z2
a3 z3
. .
. .
. .
an zn
我想将上面的数据转换为多列。我希望我的输出数据如下所示:
a1 n1 m1 x1 y1 z1
a2 n2 m2 x2 y2 z2
a3 n3 m3 x3 y3 z3
. . . . . .
. . . . . .
. . . . . .
an nn mn xn yn zn
请帮助我进行此转换。我正在使用Linux。
谢谢。
答案1
这是使用 awk 关联数组的一个很好的例子:
$ awk '{a[$1]=a[$1]" "$2} END {for (i in a) print i, a[i]}' q763033
a1 n1 m1 x1 y1 z1
a2 n2 m2 x2 y2 z2
a3 n3 m3 x3 y3 z3
an nn mn xn yn zn
输入文件 q763033 是:
$ cat q763033
a1 n1
a2 n2
a3 n3
an nn
a1 m1
a2 m2
a3 m3
an mn
a1 x1
a2 x2
a3 x3
an xn
a1 y1
a2 y2
a3 y3
an yn
a1 z1
a2 z2
a3 z3
an zn
答案2
使用datamash
:
$ datamash -sW -c $'\t' collapse 2 -g 1 <file
或者
$ datamash -sW --output-delimiter=' ' -c ' ' collapse 2 -g 1 <file
--输出分隔符=x
使用字符 X 作为输出字段分隔符。该选项会覆盖
--field-separator/-t/ --whitespace/-W
.
--折叠分隔符=x
-cx
使用字符 X 而不是逗号来分隔“折叠”或“唯一”列表中的项目。
答案3
mlr
假设空格分隔数据的第一个字段是“键”,第二个字段是“值”,您可以使用 Miller ( ) 从文件中收集每个键的所有值,file
如下所示:
$ cat file
a1 n1
a2 n2
a3 n3
an nn
a1 m1
a2 m2
a3 m3
an mn
a1 x1
a2 x2
a3 x3
an xn
a1 y1
a2 y2
a3 y3
an yn
a1 z1
a2 z2
a3 z3
an zn
$ mlr --from file --nidx nest -f 2 --ivar space
a1 n1 m1 x1 y1 z1
a2 n2 m2 x2 y2 z2
a3 n3 m3 x3 y3 z3
an nn mn xn yn zn
这会将数据读取为 Unix 工具箱格式的文件(字段由空格分隔,记录由换行符分隔),然后将数据“嵌套”在第二个字段中,创建新记录,其中包含共享的第二个字段中的所有值相同的第一个字段。空格分隔嵌套数据,因此无法判断第一个字段是一个字段,而其他字段都是另一个字段。
将输出转换为 JSON 显示实际生成的内容:
$ mlr --from file --n2j nest -f 2 --ivar space
[
{
"1": "a1",
"2": "n1 m1 x1 y1 z1"
},
{
"1": "a2",
"2": "n2 m2 x2 y2 z2"
},
{
"1": "a3",
"2": "n3 m3 x3 y3 z3"
},
{
"1": "an",
"2": "nn mn xn yn zn"
}
]
答案4
使用乐(以前称为 Perl_6)
~$ raku -ne 'BEGIN my %hash; %hash.push: .split(/ \s+ /); END .kv.put for %hash.sort;' file
这是用 Raku(Perl 编程语言家族的成员)编写的答案。 Raku 具有对 Unicode 的高级支持(如果这是您的数据集中的问题)。
使用类似 awk 的-ne
非自动打印逐行标志,我们BEGIN
声明一个%hash
(关联数组)。在代码的主体中,两列位于split
空白处并被push
添加到%hash
,它将项目理解为“键值”对。每个已知键的每个新值都会累积,然后END
您只需输出put
版本kv
(规范元素之间的间距)。
输入示例:
a1 n1
a2 n2
a3 n3
an nn
a1 m1
a2 m2
a3 m3
an mn
a1 x1
a2 x2
a3 x3
an xn
a1 y1
a2 y2
a3 y3
an yn
a1 z1
a2 z2
a3 z3
an zn
示例输出(使用上面的最终语句):
a1 n1 m1 x1 y1 z1
a2 n2 m2 x2 y2 z2
a3 n3 m3 x3 y3 z3
an nn mn xn yn zn
示例输出(使用.say
代替.kv.put
):
a1 => [n1 m1 x1 y1 z1]
a2 => [n2 m2 x2 y2 z2]
a3 => [n3 m3 x3 y3 z3]
an => [nn mn xn yn zn]
最后,如果需要,您可以转换为 JSON:
~$ raku -MJSON::Tiny -ne 'BEGIN my %hash; %hash.push: .split(/ \s+ /); END put to-json( %hash );' file
[ { "a1" : [ "n1", "m1", "x1", "y1", "z1" ] }, { "a2" : [ "n2", "m2", "x2", "y2", "z2" ] }, { "a3" : [ "n3", "m3", "x3", "y3", "z3" ] }, { "an" : [ "nn", "mn", "xn", "yn", "zn" ] } ]