代码之家  ›  专栏  ›  技术社区  ›  hatmatrix

从文件中提取特定的行集

  •  1
  • hatmatrix  · 技术社区  · 15 年前

    我有许多大的(~30MB一个)制表符分隔的文本文件,带有可变宽度的行。我想从第n行(这里,n=4)和最后一行(最后一行是空的)旁边提取第2个字段。我可以使用awk分别获取它们:

    awk 'NR==4{print $2}' filename.dat
    

    而且(我不完全理解,但是)

    awk '{y=x "\n" $2};END{print y}' filename.dat
    

    但有没有办法让他们在一个电话里聚在一起?我更广泛的意图是将其包装在Python脚本中,以便从不同目录中的大量文件(数千个)中获取这些值,并且我希望减少系统调用的数量。多谢了-

    编辑: 我知道我可以用Python读取整个文件来提取这些值,但是我认为awk可能更适合这个任务(必须处理大文件末尾附近的两个值之一)。

    4 回复  |  直到 15 年前
        1
  •  1
  •   John La Rooy    15 年前

    下面介绍如何在Python中实现这一点,而不必读取整个文件

    要获得第n行,您别无选择,只能读取文件到第n行,因为行的宽度是可变的。

    猜测

    read() 从你想要的那一点开始。计算换行符的数量-至少需要两个。如果新行数少于2行,请加倍猜测并重试

    拆分在换行处读取的数据-您查找的行将是拆分中倒数第二项

        2
  •  3
  •   Ignacio Vazquez-Abrams    15 年前
    awk 'NR==4{print $2};{y=x "\n" $2};END{print y}' filename.dat
    
        3
  •  2
  •   glenn jackman    15 年前

    awk -v lines=$( wc -l < filename.dat ) -v n=4 '
        NR == n || NR == lines-1 {print $2}
    ' filename.dat
    

    注意,在 wc < 重定向以避免打印文件名。

        4
  •  1
  •   hatmatrix    15 年前

    这是我在Python中的解决方案。灵感来自 this other code

    def readfields(filename,nfromtop=3,nfrombottom=-2,fieldnum=1,blocksize=4096):
        f = open(filename,'r')
        out = ''
        for i,line in enumerate(f):
            if i==nfromtop:
                out += line.split('\t')[fieldnum]+'\t'
                break
        f.seek(-blocksize,2)
        out += str.split(f.read(blocksize),'\n')[nfrombottom].split('\t')[fieldnum]
        return out
    

    当我分析它的时候,这个差异比调用awk的解决方案快了0.09秒( awk 'NR==4{print $2};{y=x $2};END{print y}' filename.dat )与子流程模块。不是一个dealbreaker,但是当脚本的其余部分是Python时,它似乎是有回报的(特别是因为我有很多这样的文件)。

    推荐文章