繁体   English   中英

从文件中提取特定的行集

[英]extract specific set of lines from files

我有许多大的(〜30 MB /片)制表符分隔的文本文件,带有可变宽度的行。 我想从第n个(这里n = 4)和倒数第二行(最后一行为空)中提取第二个字段。 我可以使用awk分别获得它们:

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

和(我不完全理解这一点,但是)

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

但是有没有办法一次召集他们呢? 我更广泛的意图是将其包装在Python脚本中,以从单独目录中的大量文件(数千个)中获取这些值,并且我希望减少系统调用的次数。 谢谢一堆-

编辑:我知道我可以使用Python读取整个文件以提取这些值,但认为awk可能更适合该任务(与大文件末尾的两个值之一有关)。

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

您可以将行数传递给awk:

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

注意,在wc命令中,使用<重定向以避免打印文件名。

这是在不读取整个文件的情况下用Python实现的方法

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

要获得倒数第二行,请猜测该行可能有多长(慷慨),并在文件末尾查找到那么多字节。

从您要寻找的位置开始read() 计算换行符的数量-您至少需要两个。 如果少于2个换行符,则将您的猜测加倍,然后重试

在换行符处拆分读取的数据-您要查找的行将是拆分中倒数第二个条目

这是我在Python中的解决方案。 受到其他代码的启发:

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( awk 'NR==4{print $2};{y=x $2};END{print y}' filename.dat )的解决方案相比,差异要快0.09秒。 这不是一个大问题,但是当脚本的其余部分在Python中显示时,似乎有收获(特别是因为我有很多这样的文件)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM