ファイルのある列の一致するエントリを別のファイルの別の列で置き換える


8

次のような2つのタブ区切りファイルがあります。

file1:

NC_008146.1     WP_011558474.1  1155234 1156286 44173
NC_008146.1     WP_011558475.1  1156298 1156807 12
NC_008146.1     WP_011558476.1  1156804 1157820 -3
NC_008705.1     WP_011558474.1  1159543 1160595 42748
NC_008705.1     WP_011558475.1  1160607 1161116 12
NC_008705.1     WP_011558476.1  1161113 1162129 -3
NC_009077.1     WP_011559727.1  2481079 2481633 8
NC_009077.1     WP_011854835.1  1163068 1164120 42559
NC_009077.1     WP_011854836.1  1164127 1164636 7

file2:

NC_008146.1     GCF_000014165.1_ASM1416v1_protein.faa
NC_008705.1     GCF_000015405.1_ASM1540v1_protein.faa
NC_009077.1     GCF_000016005.1_ASM1600v1_protein.faa

file1の列1をfile2に一致させ、それ自体をファイル2のそれぞれの列2エントリで置き換えたいのですが、出力は次のようになります。

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

姉妹サイトのバイオインフォマティクスにも興味があるようです。
terdon

リンク@terdonをありがとう!
BhushanDhamale

回答:


14

あなたはこれを使って非常に簡単にこれを行うことができますawk

$ awk 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa WP_011558474.1 1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa WP_011558475.1 1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa WP_011558476.1 1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa WP_011558474.1 1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa WP_011558475.1 1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa WP_011558476.1 1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa WP_011559727.1 2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa WP_011854835.1 1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa WP_011854836.1 1164127 1164636 7

または、タブ区切りファイルのように見えるので:

$ awk -vOFS="\t" 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa   WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854836.1  1164127 1164636 7

これは、すべてのRefSeq(NC_*)idにfile1に対応するエントリがあることを前提としていfile2ます。

説明

  • NR==FNR:NRは現在の行番号、FNRは現在のファイルの行番号です。2つは、最初のファイル(ここではfile2)が読み取られている間のみ同一になります。
  • a[$1]=$2; next:これが最初のファイルである場合(上記を参照)、2番目のフィールドをキーが1番目のフィールドである配列に保存します。次に、行に移動しnextます。これにより、次のブロックが最初のファイルに対して実行されなくなります。
  • {$1=a[$1]; print}:次に、2番目のファイルで、1番目のフィールドを1番目のフィールドの配列に保存された値a(つまり、に関連付けられた値file2)に設定し、結果の行を出力します。

1
NR == FNR最初のファイルが空の場合、正しく動作しません。回避策については、これと関連する回答を参照してください
iruvar

3
最初のファイルが空の場合、@ iruvarは何もうまくいきません。そのため、それが関連している理由は本当にわかりません。ここでの要点は、2つのファイルのデータを結合することです。どちらかのファイルが空の場合、演習全体は無意味です。
terdon

この特定のケースfile2では申し訳ありませんfile1が、空ではありませんでした。file2が空の場合の正常な動作は、の内容を報告することですfile1。伴う問題はNR == FNR、それが内容上で実行に関連したコードであるfile1場合にfile2空である
iruvar

3
@iruvarどちらかのファイルが空の場合、ここでは正常な動作はありません。それが私が言っていることです:)それでそれを優雅にケースに対処させようとすることは無意味です。そして、いずれにせよ、どちらかのファイルがここで空の場合、何も出力されません。これは実際には最も健全なアプローチのように思えますが、間違ったデータよりもデータを取得したくないのです。
terdon

17

ファイルがソートされていると想定して、awkは不要です。coreutilsjoinを使用できます。

join -o '2.2 1.2 1.3 1.4 1.5' file1 file2

出力:

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

ファイルが並べ替えられていない場合は、まずファイルを並べ替え(sort file1 > file1.sorted; sort file2 > file2.sorted)てから上記のコマンドを使用するか、シェルが<()構成をサポートしている場合(bashがサポートしている場合)は、次のいずれかを実行できます。

join -o '2.2 1.2 1.3 1.4 1.5' <(sort file1) <(sort file2)

0

以下のコマンドでテストし、正常に動作しました

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done

出力

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done


GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.