![如何将列转换为每列有多个值的行?](https://linux22.com/image/155693/%E5%A6%82%E4%BD%95%E5%B0%86%E5%88%97%E8%BD%AC%E6%8D%A2%E4%B8%BA%E6%AF%8F%E5%88%97%E6%9C%89%E5%A4%9A%E4%B8%AA%E5%80%BC%E7%9A%84%E8%A1%8C%EF%BC%9F.png)
我有一个包含如下数据的文件:
1,2,3 4,5,6 7,8,9 12,22,0
我想制作一个有 4 列的表a,b,c,d
,其中有 4 列,这样该列a
具有第一列的值,该列b
具有第二列的相应值,依此类推。
在上面的示例中,列将类似于:
a b c d
1 4 7 12
2 5 8 22
3 6 9 0
还有没有。特定行的列中的条目将相同。然而,不同行的这些条目可能不同,例如,某些行每列只能有 1 个逗号分隔的条目,有些甚至可以有 10 个。
答案1
目前尚不清楚您期望如何命名列(用户输入,每个要使用的列的预定义名称,或者其他方式)。
只是为了将字符串拆分为列,您可以使用sed
:
echo 1,2,3 4,5,6 7,8,9 12,22,0 | sed -n 'h;:a;g;s/,[^ ]*//gp;g;s/^[^, ]*,//;s/ [^,]*,/ /g;h;ta;p'
这里sed
将整个字符串复制到缓冲区 ( h
),迭代循环 ( :a
.. ta
) 中的行,从缓冲区 ( ) 获取复制的字符串g
,从每个部分获取第一个数字 (first s
) 并打印它 ( p
),然后再次检索未更改的字符串,从中删除第一个数字(第二个和第三个s
)并将修改后的字符串放回缓冲区(h
)。当我们处于,
字符串状态时,这种情况仍在继续。一旦它消失,我们就打印剩下的内容p
。
答案2
您可以完成所需的任务:
$ sed -Ee '
s/^/ /;y/ /\n/
:loop
s/(\n.*)\n([^,]*),/\2 \1 /
tloop
s/(.*) \n([^,]*),/\2 \1\n/
P;/,/D;s/.*\n//
' inp
接下来的方法是通过从每列中选取前导列元素来塑造要打印的行。
另一种方法可能是将列拆分为基于逗号拆分的数组。然后移出前导元素,直到用完任何子数组中的元素为止,因为每行它们的数量是相同的。
$ perl -lane '$,=" ";
my @A = map { [split /,/] } @F;
print map { shift @$_ } @A while @{$A[0]};
' inp