次のようなファイル(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%
2つの>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スクリプトを使用してこれを行う方法はありますか?
Perlとgrepを使用した2部構成のソリューション:
Perl -pe 's/^>C \d+$/\0$&/' file1 | grep -zFf file2
>C <some number>
はグループを区切るので、それに一致し、各グループの前にASCII nul文字(\0
)]を挿入します。-z
)、NULで区切られた行(-f file2
)を処理するgrep
の機能を利用できます。Awkでは、レコードセパレータとして>C
を使用し、各レコードの前にNULを出力することにより、同様のことを行います。
awk -v RS='>C ' '{printf "\0>C %s", $0}' foo | grep -zFf ba
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
ここでは、最初に区切り文字>C
を使用して「file_1」をサブグループに分割し、次にサブグループ内の「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])