
別のファイルのIDに基づいてテキストブロックを抽出したいと思います。
入力する
>Feature scaffold1
1 100 g
101 200 g
201 300 g
500 500 r
900 1000 r
>Feature scaffold2
1 100 g
01 500 g
200 300 r
>Feature scaffold3
10 500 g
100 200 r
>Feature scaffold4
10 300 g
500 600 r
>Feature scaffold5
1 1000 r
id.txt
scaffold1
scaffold3
scaffold4
出力.txt
>Feature scaffold1
1 100 g
101 200 g
201 300 g
500 500 r
900 1000 r
>Feature scaffold3
10 500 g
100 200 r
>Feature scaffold4
10 300 g
500 600 r
だから私はid.txtに存在するIDのテキストブロックが欲しいです。これを行う方法はありますか?
答え1
短いawk
解決策:
awk 'NR==FNR{ a[$1]; next }/^>Feature/{ f=($2 in a) }f' id.txt input.txt
NR==FNR{ ... }
- 最初の入力ファイル(例id.txt
:)を処理します。a[$1]
- すべてキャプチャ「足場」配列に保存されたIDa
next
- 次のレコードに移動
/^>Feature/
- 次に始まるモデル行を見つけました>Feature
(2番目の入力ファイルを処理するときinput.txt
):f=($2 in a)
f
- 現在の設定に基づいてアクティビティにフラグを付けます。「足場」id(2番目のフィールドとして表示$2
)がids配列に表示されます。a
f
- このフラグの活動によって、すべてのブロックは処理または処理されません。
出力:
>Feature scaffold1
1 100 g
101 200 g
201 300 g
500 500 r
900 1000 r
>Feature scaffold3
10 500 g
100 200 r
>Feature scaffold4
10 300 g
500 600 r
答え2
Perlソリューション:
#!/usr/bin/perl
open $ids, '<', 'id.txt' or die $!;
chomp, $h{$_} = 1 while <$ids>;
open $in, '<', 'input.txt' or die $!;
while (<$in>) {
$id = $1 if />Feature (.*)/;
print if $h{$id};
}
まず、IDをハッシュにロードし、入力ファイルを1行ずつ読み、必要に応じて現在のIDを設定し、ハッシュに現在のIDが保存されていることを確認し、保存された行のみを印刷します。
答え3
私は次の方法でそれをしました
for i in scaffold1 scaffold3 scaffold4
> do
> sed -n "/$i/,/scaffold/p" inputfile | sed '$d'
> done
出力。
Feature scaffold1
1 100 g
101 200 g
201 300 g
500 500 r
900 1000 r
>Feature scaffold3
10 500 g
100 200 r
>Feature scaffold4
10 300 g
500 600 r