繁体   English   中英

如何在AWK或Python中从多个文本文件中打印第二行和最后三行?

[英]How can I print second and last three lines from multiple text files, in AWK or Python?

使用awk,我很难尝试从多个文本文件中打印第二行和最后三行。 另外,我想将输出定向到文本文件。

任何帮助或建议,将不胜感激。

这样做的好处是整个文件不会保存在内存中。

awk 'NR == 2 {print}; {line1 = line2; line2 = line3; line3 = $0} END {print line1; print line2; print line3}' files*

编辑:

以下内容使用了gawk手册中的某些代码,这些代码可移植到其他版本的AWK。 它提供了按文件处理。 请注意, gawk版本4提供了BEGINFILEENDFILE规则。

#!/usr/bin/awk -f
function beginfile (file) {
    line1 = line2 = line3 = ""
}

function endfile (file) {
    print line1; print line2; print line3
}

FILENAME != _oldfilename \
     {
         if (_oldfilename != "")
             endfile(_oldfilename)
         _oldfilename = FILENAME
         beginfile(FILENAME)
     }

     END   { endfile(FILENAME) }

FNR == 2 {
    print
}

{
    line1 = line2; line2 = line3; line3 = $0
}

将其另存为文件,也许称其为“ fileparts”。 然后做:

chmod u+x fileparts

然后,您可以执行以下操作:

./fileparts file1 file2 anotherfile somemorefiles*.txt

它将在一组输出中输出每个文件的第二行和最后三行。

或者,您可以对其进行修改以输出到单独的文件,或者可以使用Shell循环来输出到单独的文件:

for file in file1 file2 anotherfile somemorefiles*.txt
do
    ./fileparts "$file" > "$file.out"
done

您可以根据需要命名输出文件。 它们将是文本文件。

为避免一次将整个文件读入内存,请使用maxlen为3的双端队列来创建滚动缓冲区以捕获最后3行:

from collections import deque
def get2ndAndLast3LinesFrom(filename):
    with open(filename) as infile:
        # advance past first line
        next(infile)
        # capture second line
        second = next(infile)
        # iterate over the rest of the file a line at a time, saving the final 3
        last3 = deque(maxlen=3)
        last3.extend(infile)        
        return second, list(last3)

您可以将这种方法推广到可以迭代的函数:

def lastN(n, seq):
    buf = deque(maxlen=n)
    buf.extend(seq)
    return list(buf)

然后,您可以使用partial创建不同长度的“ last-n”函数:

from functools import partial
last3 = partial(lastN, 3)

print last3(xrange(100000000)) # or just use range in Py3

如果您不希望使用Python或AWK来实现,则可以使用Shell和标准的head / tail实用程序非常简单地执行操作。

for file in "$@"; do
    head -n2 "$file" | tail -n1
    tail -n3 "$file"
done

您也可以将其包装在函数中或放在脚本中,然后根据需要从Python或AWK中使用subprocess.check_output()进行调用,但是在这种情况下,使用本机方法可能比使用本机方法更容易产生一个外部过程。

这可以工作,但是它确实将整个文件加载到内存中,如果文件很大,这可能不是理想的选择。

text = filename.readlines()

print text[2] # print second line

for i in range(1,4): # print last three lines
    print text[-i]

也有一些讨论很好的替代这里

我不知道awk,但是如果您使用的是Python,我想您将需要这样的东西

inf = open('test1.txt','rU')
lines = inf.readlines()
outf = open('Spreadsheet.ods','w')
outf.write(str(lines[1]))
outf.write(str(lines[-3]))
outf.write(str(lines[-2]))
outf.write(str(lines[-1]))
outf.close()
inf.close()

暂无
暂无

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

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