根据出现次数操作awk输出

时间:2014-04-24 18:21:31

标签: awk

我不知道怎么说得好。我有一个输入文件,每行的第一列是索引。我需要将此输入文件转换为多列输出文件,以便每个此类列的起始索引匹配。

我有一个输入文件,格式如下:

1 11.32 12.55 
1 13.32 17.55
1 56.77 33.22
2 34.22 1.112
3 12.13 13.14
3 12.55 34.55 
3 22.44 12.33
3 44.32 77.44

预期输出应为:

1 11.32 12.55  2 34.22 1.112 3 12.13 13.14
1 13.32 17.55                3 12.55 34.55 
1 56.77 33.22                3 22.44 12.33
                             3 44.32 77.44

我有一种简单的方法可以在awk中执行此操作吗?

2 个答案:

答案 0 :(得分:2)

这样的事情,在bash中:

paste <(grep '^1 ' input.txt) <(grep '^2 ' input.txt) <(grep '^3 ' input.txt)
如果您不想使用默认的标签字符,

paste可以选择设置分隔符,或者您可以使用expand对标签进行后期处理...

编辑:对于包含更多标签的输入文件,您可以采用以下方法:

awk '{print > "/tmp/output" $1 ".txt"}' input.txt
paste /tmp/output*.txt > final-output.txt

awk行将每一行输出到以该行的第一个字段命名的文件,然后paste重新组合它们。

编辑:正如下面的评论所指出的,如果最终有9个以上的中间文件,则可能会出现问题。解决这个问题的方法是这样的:

paste /tmp/output[0-9].txt /tmp/output[0-9][0-9].txt > final-output.txt

如果您有超过99个文件...或者超过999,则根据需要添加其他参数...但如果是这种情况,那么pythonperl解决方案可能会是一条更好的路线...

答案 1 :(得分:1)

如果你只需要独立运行列(不试图在列之间排列匹配的项目或类似的东西),那么最简单的解决方案可能是这样的:

awk '{print > $1".OUT"}' FILE; paste 1.OUT 2.OUT 3.OUT

唯一的问题是它不会填写缺失的列,因此您需要填写自己的列以排列列。

如果预先知道列宽(并且每列都相同),则使用:

paste 1.OUT 2.OUT 3.OUT | sed -e 's/^\t/             \t/;s/\t\t/\t             \t/'

这些空格是列的宽度应该可以得到你想要的。我觉得应该有一种方法以更自动化的方式做到这一点,但不能想到一个随便。