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

2024-05-29 09:51:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用一个数据集:

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会不会更简单?你知道吗

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


Tags: 数据代码alisg空白glb兴趣pg
3条回答

据我所知,您在第一个字段上进行匹配,并且文件已排序。在这种情况下,请尝试:

$ 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""}

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

另一个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进行预处理。不要求键是连续的或排序的。你知道吗

在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    

相关问题 更多 >

    热门问题