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])