他のファイルからテキストブロックを抽出する

他のファイルからテキストブロックを抽出する

別のファイルの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

関連情報