【问题标题】:print line with match and next line, but only first match, from a file of strings从字符串文件中打印带有匹配和下一行的行,但仅是第一个匹配
【发布时间】:2015-08-28 01:20:20
【问题描述】:

我有两个文件,一个带有换行符分隔的数字 ID 列表

>cat list.txt
3342
232
...

还有一个在后面的行中有这些 ID 和一些序列数据

>cat Seqeunce.txt

>600
ATCGCGG
>3342
ACTCGGTC
>232
TGTGCT
>3342
ACGCGGTC

我想打印 ID 匹配的所有行和下一行,但仅在第一次找到匹配项时打印。 因此,输出将是:

> ...some code... list.txt Sequence.txt
>3342
ACTCGGTC
>232
TGTGCT

请注意,只有第一次出现 ID 3342 的行和下一行会被打印

我尝试使用 grep,

grep -f list.txt -A 1 -m 1 Sequence.txt 

但它不起作用。只需使用实际 ID 运行 grep -A 1 和 -m 1 即可产生我想要的结果,但我有数千个 ID,无法手动运行每个 ID。

【问题讨论】:

  • 这需要为 list.txt 中的每个 id 重新扫描 sequence.txt。如果您有成千上万的人,您将等待数小时才能完成硬盘驱动器。如果您提前知道 id (list.txt),则可以一次性完成。但是,您需要一个脚本来执行此操作。您可以使用this 工具创建一个正则表达式树,然后将数据文件与之匹配。结果是即时的。
  • 一个很好的观点。如果您确实有数千个 ID 要查找,则应该使用适合查找的工具...您可以做一个非常简单的程序,将 Sequence.txt 读入映射/哈希/关联数组(无论语言如何称呼它们),然后您可以快速轻松地执行查找。

标签: regex awk grep


【解决方案1】:
awk 'NR==FNR{tgts[">"$0]; next} $0 in tgts{c=2; delete tgts[$0]} c&&c--' list.txt sequence.txt
>3342
ACTCGGTC
>232
TGTGCT

【讨论】:

  • 它读取:如果 c 不为零,则递减 c,如果结果是 c 仍然不为零,则调用打印当前记录的默认操作。你可能认为你可以做类似c-->0 的事情,但我不相信在一个巨大的文件上c-- 不会超过一个变量的大小并重新变成正数(比如 -MAXINT - 1 = MAXINT)。您可以在stackoverflow.com/a/18409469/1745001 看到它的更多用途
【解决方案2】:

你可以使用这个 awk 命令:

awk -F'>' 'NR==FNR{a[$1];next} $2 in a{p=1; print; delete a[$2]; next}; 
      p; {p=0}' list.txt Sequence.txt
>3342
ACTCGGTC
>232
TGTGCT

【讨论】:

    【解决方案3】:

    你离得很近。试试这个:

    for id in `cat list.txt`; do grep -A 1 -m 1 -x ">$id" Sequence.txt; done
    

    【讨论】:

    • @EdMorton - D'oh。你是对的。我已经解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多