如果一组行包含特定字符串,则打印它们

如果一组行包含特定字符串,则打印它们

file 1我有一个如下所示的文件( ):

>C 0
0   4231aa, >A6_03412... at 1:4226:1:4240/95.44%
1   4240aa, >A5_01600... *
>C 1
0   4159aa, >FG1_03697... *
>C 2
0   3942aa, >A3_03045... at 1:3942:1:3945/96.50%
1   3945aa, >A4_03199... *
2   3942aa, >A7_02989... at 1:3942:1:3945/92.11%
3   3941aa, >A6_03202... at 1:1:1:1/96.35%

我将两者之间的部分视为>C子群。例如,这是一个子群

 >C 0
 0  4231aa, >A6_03412... at 1:4226:1:4240/95.44%
 1  4240aa, >A5_01600... *

然后我有另一个文件(file 2),其中包含子组内的字符串:

A6_03412
A4_03199
.....

我想打印包含字符串的所有子组file 2。因此,考虑到file 2我只有上述字符串,输出应该是:

>C 0
0   4231aa, >A6_03412... at 1:4226:1:4240/95.44%
1   4240aa, >A5_01600... *
>C 2
0   3942aa, >A3_03045... at 1:3942:1:3945/96.50%
1   3945aa, >A4_03199... *
2   3942aa, >A7_02989... at 1:3942:1:3945/92.11%
3   3941aa, >A6_03202... at 1:1:1:1/96.35%

这是一个难题,有什么建议可以用 bash 脚本来做到这一点吗?

答案1

使用 Perl 和 grep 的两部分解决方案:

perl -pe 's/^>C \d+$/\0$&/' file1 | grep -zFf file2
  • 由于>C <some number>将组分开,我匹配它并\0在每个组前面插入一个 ASCII 空字符 ()。
  • 然后,我可以利用grep处理 NUL 分隔行的能力(-z),同时从文件中读取模式(-f file2)。

使用 awk,我会做类似的事情,使用它>C作为记录分隔符并在每个记录前打印一个 NUL:

awk -v RS='>C ' '{printf "\0>C %s", $0}' foo | grep -zFf ba

答案2

以下是一个 Python 方法:

#!/usr/bin/env python2
with open('file_1') as f_1, open('file_2') as f_2:
    f_1_subgroups = f_1.read().split('>C')
    f_2_lines = [line.rstrip() for line in f_2]
    for subgroup in f_1_subgroups:
        for line in f_2_lines:
            if line in subgroup:
                print '>C' + subgroup

这里我们首先使用分隔符将“file_1”拆分为子组>C,然后在子组中搜索“file_2”的行。如果找到,我们就打印该子组。

使用列表理解:

#!/usr/bin/env python2
with open('file_1') as f_1, open('file_2') as f_2:
    f_1_subgroups = f_1.read().split('>C')
    f_2_lines = [line.rstrip() for line in f_2]
    print ''.join(['>C' + subgroup for line in f_2_lines for subgroup in f_1_subgroups if line in subgroup])

相关内容