共通のヘッダーを使用して2つのファイルの行をマージするにはどうすればよいですか?


8

ヘッダーとして存在する共通データに基づいて2つのファイルをマージしたい。

以下はその例です

ファイル1

>Feature scaffold1
1   100  g
101 200  g
201 300  g
>Feature scaffold2
1   100  g
01  500  g
>Feature scaffold3
10  500  g
>Feature scaffold4
10  300  g

ファイル2

>Feature scaffold1
500 500 r
900 1000    r
>Feature scaffold2
200 300 r
>Feature scaffold3
100 200 r
>Feature scaffold4
500 600 r
>Feature scaffold5
1   1000    r

そして、これが私が欲しい種類の出力です:

>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

私はいくつかのawkとsedを試しましたが、明らかに成功していません。どうすればこれを行うことができますか?

回答:


7

Awk 解決:

awk '/^>/{ k=$1 FS $2 }
     NR==FNR{ 
         if (!/^>/) a[k]=(a[k]!="")? a[k] ORS $0: $0; next
     }
     k in a{ 
         print $0 ORS a[k]; delete a[k]; next 
     }1' file1 file2
  • /^>/{ k=$1 FS $2 }- ヘッダー行に遭遇したとき(つまり>Feature ...)-1 k番目$1と2番目の$2フィールドからキーを作成します
  • NR==FNR{ ... }-最初の入力ファイルを処理しています(file1):
    • if (!/^>/) a[k]=(a[k]!="")? a[k] ORS $0: $0- 現在のキーを使用して非ヘッダー行を配列に蓄積しaますk
    • next -次のレコードにジャンプ
  • k in a- file2レコードに基づく現在のキーが配列にある場合afile1レコードに基づく):
    • print $0 ORS a[k] -関連レコードを印刷する
    • delete a[k] -処理されたアイテムを削除します

出力:

>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

4

別のアプローチとそれをより簡単にすること。

grep -v '^scaffold' <(awk -v RS='>Feature ' \
    'NF{s[$1]=s[$1]$0} END{for (x in s)print RS""s[x]}' file[12])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.