2014-12-04 31 views
1

我有一个像这样与行的文件块:保持第一线的相关线路

r1 300 #keep this one 
r1 200 
r1 100 
r1 100 
r2 100 # " 
r2 200 
r3 200 # " 
r3 100 
r3 300 

我只需要保持各个“块”的第一行(R1,R2,R3等)

期望的输出:

r1 300 
r2 100 
r3 200 

任何建议?

+0

难道你不能'awk'!a [$ 1] ++''? – 2014-12-04 15:27:23

回答

2
with open('path/to/input') as infile: 
    curr = None 
    for line in infile: 
     if line == curr: 
      continue 
     print(line) 
     curr = line 

或者使用bash:

cat path/to/file | uniq 

或用itertools:

import itertools 

with open('path/to/file') as infile: 
    for line,_stuff in itertools.groupby(infile): 
     print(line) 
+1

不错的python解决方案,虽然也是对'cat'的无用使用,但使用'uniq'的解决方案不起作用(每行都被打印)。 – 2014-12-04 15:35:26

+0

事实上,我不明白第一个Python是如何检测行上第一个单词的任何变化的?它看起来像比较整条线。 – 2014-12-04 15:39:24

6

你可以保持到第一列,仅印刷轨道的变化时,它是不同的:

awk '$1 != last; {last = $1}' file 

分号前的部分h作为一个隐含的{print}操作,所以如果第一列不等于last的值(已编辑,谢谢),将打印该行。分号后的程序块无条件运行,并将第一列的值赋予变量last

就更安全是分开处理的第一行(因为我原本做),并添加一个额外的条件:

awk '!last || $1 != last; {last = $1}' file 

该处理的情况时,在第一行的第一列包含数字0,在它被分配一个值之前将被评估为等于last

,如果从不重复第一列的内容,你可以使脚本更简单,因为在评论中指出(谢谢):

awk '!seen[$1]++' file 

仅打印线,其第一列还没有被看到,因为seen[$1]评估为假。 ++意味着在后续具有相同值$1的行上,seen[$1]已递增,因此计算结果为true。

+2

可以更简单:'awk'![$ 1] ++'' – 2014-12-04 15:27:28

+1

你不需要'!last ||'如果'last'不存在,它不会匹配'$ 1'.Could just是'awk'$ 1!= x && x = $ 1'' – 2014-12-04 15:47:27

+0

对于我以前的评论,例外情况是如果$ 1为0,这看起来不像OP数据中的可能性 – 2014-12-04 15:53:41