根据列中的匹配重新排列文本文件

时间:2016-08-16 23:58:02

标签: python unix awk

我正在使用数据集:

ALI P 18:00:40.583 0.0

ALI S 18:00:58.188 1.4

BRD Pg 18:00:48.918 0.4

BRD Sg 18:01:09.437 -1.8

GAN Pn 18:00:58.207 -0.0

GAN Sn 18:01:27.791 0.1

GLB P 18:00:27.265 -0.4

GLB S 18:00:34.187 0.1

GOB S 18:01:13.638 -0.6

IML Pg 18:00:52.264 -0.6

使用AWK,我需要匹配的行,打印到同一行。

即。

ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4

BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8

我一直在尝试各种不同的想法,但无法找到代码来执行此操作。 我一直试图按照我的上司的指示使用AWK。有兴趣看看它在Python中会更容易吗?

(注意线之间的空白以保留结构)

3 个答案:

答案 0 :(得分:2)

据我了解,您在第一个字段上匹配,文件已排序。在这种情况下,请尝试:

$ awk 'NR>1{printf "%s%s",($1==last?" ":"\n"),$0}; NR==1{printf "%s",$0} {last=$1} END{print""}' file
ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4
BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8
GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1
GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1
GOB S 18:01:13.638 -0.6
IML Pg 18:00:52.264 -0.6

如何运作

  • NR==1{printf "%s",$0}

    对于第一行,我们打印时没有尾随换行符。

  • NR>1{printf "%s%s",($1==last?" ":"\n"),$0}

    对于第一个之后的行,我们会在第一个字段匹配时打印一个空格,如果不匹配则打印换行符,然后是该行。

    这里棘手的部分是三元语句$1==last?" ":"\n"。这只是测试第一个字段是否等于最后一个字段。如果是,则返回?之后的字符串。如果不是,则返回:之后的字符串。

  • last=$1

    我们将变量last更新为最新的第一个字段。

  • END{print""}

    在我们完成阅读文件并确保我们有一个完整的最后一行后,我们会打印一个换行符。

答案 1 :(得分:1)

另一个awk

$ awk '{a[$1]=a[$1]?a[$1] FS $0:$0} 
    END{for(k in a) print a[k] | "sort" }' file | column -t

ALI  P   18:00:40.583  0.0   ALI  S   18:00:58.188  1.4
BRD  Pg  18:00:48.918  0.4   BRD  Sg  18:01:09.437  -1.8
GAN  Pn  18:00:58.207  -0.0  GAN  Sn  18:01:27.791  0.1
GLB  P   18:00:27.265  -0.4  GLB  S   18:00:34.187  0.1
GOB  S   18:01:13.638  -0.6
IML  Pg  18:00:52.264  -0.6

使用相同的键累积记录,在末尾打印并按键(按键)排序column以获得漂亮。不要求密钥是连续的或排序的。

答案 2 :(得分:1)

这可以用Python来解决,如下所示:

from itertools import groupby

data = """ALI P 18:00:40.583 0.0
ALI S 18:00:58.188 1.4
BRD Pg 18:00:48.918 0.4
BRD Sg 18:01:09.437 -1.8
GAN Pn 18:00:58.207 -0.0
GAN Sn 18:01:27.791 0.1
GLB P 18:00:27.265 -0.4
GLB S 18:00:34.187 0.1
GOB S 18:01:13.638 -0.6
IML Pg 18:00:52.264 -0.6"""    

print '\n'.join(' '.join(g) for k,g in groupby(data.splitlines(), key=lambda x: x.split()[0]))

这会显示:

ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4
BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8
GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1
GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1
GOB S 18:01:13.638 -0.6
IML Pg 18:00:52.264 -0.6    
相关问题