从文件中提取键周围的行

从文件中提取键周围的行

我有一个大约有 1500 万行的大文件。奇数行包含键(但不仅仅是键),偶数行是数据。也就是说,该文件类似于:

WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808

这里的键是ASDFTYSR、 和WRTZ

我有大约 100000 个键的列表。我想提取与这些键对应的数据(两行)。

我尝试的一种方法是在grep包含键的行中获取行号,然后在循环中使用headand提取该行和下一行。tail然而,这似乎需要很长时间才能运行。

有没有更有效的方法来做到这一点?

答案1

如果偶数行和奇数行没有变化。然后尝试使用下面的命令

awk 'NR%2{printf $1"-";next;}1' <Filename>

上述命令的输出将是

WRTZ-1287998798

ASDF-9408654860

TYSR-9809804090

ASDF-4950409808

答案2

一个小的 awk 脚本就可以完成这项工作。通过阅读 awk man 手册很容易理解。

    #!/usr/bin/awk -f
    BEGIN{got=0;linenum=0}
    /ASDF/{printf ("%s ",$1); got=1;linenum=NR+1}
    /TYSR/{printf ("%s ",$1); got=1;linenum=NR+1}
    /WRTZ/{printf ("%s ",$1); got=1;linenum=NR+1}
    /^[0-9]/{if ( ( got == 1 ) && ( linenum == NR) ) {
    printf("%s\n",$1)
    got=0
    linenum=0
    }}

输出将是这样的:

    ./awk_script data_file

    WRTZ 1287998798
    ASDF 9408654860
    TYSR 9809804090
    ASDF 4950409808

您可以修改它以满足您自己的需要!

答案3

您最可能想要的是利用grep,及其本机选项来显示比赛周围的 +/- 线:

   Context Line Control
       -A NUM, --after-context=NUM
              Print NUM lines of trailing context after matching lines.  Places a line containing a group separator (--)  between  contiguous
              groups of matches.  With the -o or --only-matching option, this has no effect and a warning is given.

       -B NUM, --before-context=NUM
              Print  NUM  lines of leading context before matching lines.  Places a line containing a group separator (--) between contiguous
              groups of matches.  With the -o or --only-matching option, this has no effect and a warning is given.

       -C NUM, -NUM, --context=NUM
              Print NUM lines of output context.  Places a line containing a group separator (--) between contiguous groups of matches.  With
              the -o or --only-matching option, this has no effect and a warning is given.

答案4

使用(以前称为 Perl_6)

如果您正在寻找配对线路,那么rotor/batch它们:

~$ raku -e '.put for lines.rotor(2, partial => True).map: *.words[0,2];'  file

#OR

~$ raku -e '.put for lines.batch(2).map: *.words[0,2];'  file

Raku 的rotor/batch例程可以采用用户定义数量(例如23、4 等)的元素(例如lines)并将它们分组在一起。如果您预期完整的配对(即文件包含偶数行),您可以简单地使用rotor并删除该partial => True参数。

注意:此代码根据空格分隔的.words标准保留元素。如果(比方说)某些对words在第一行有两个,而其他对words在第一行有三个(或更多),您可能会遇到问题。

您可以通过选择第一个word来避免此问题每个线,像这样:

~$ raku -e '.put for lines.rotor(2).map( *.map: *.words[0]);'  file

#OR (using `>>` hyper notation):

~$ raku -e '.put for lines.rotor(2)>>.map: *.words[0];'  file

输入示例:

WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808

示例输出(所有代码示例):

WRTZ 1287998798
ASDF 9408654860
TYSR 9809804090
ASDF 4950409808

https://docs.raku.org/routine/rotor
https://raku.org

相关内容