2つのファイルの最初の列に基づいて2つのタブで区切られたファイルを比較し、出力ファイルに一致するものと一致しないものを印刷します。

2つのファイルの最初の列に基づいて2つのタブで区切られたファイルを比較し、出力ファイルに一致するものと一致しないものを印刷します。

2つのタブで区切られたファイル(fileA.txtとfileB.txt)があり、fileA.txtの最初の列をfileB.txtの最初の列と比較する必要があり、2番目の列の内容を印刷しようとしています。出力ファイルfileB.txt。以下は私です。

fileA.txt

id
chr1_45796849_A_T
chr1_45796854_C_T
chr1_45797174_T_A
chr1_45796852_G_C
chr19_9018540_A_G
chr19_9002576_T_C
chr1_45797487_A_G
chr1_45797153_A_T
chr1_45797750_C_T

FileB.txt

chr_pos             freq.var
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931

以下は予想される結果です

id                  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796854_C_T   0.015872901
chr1_45797174_T_A   
chr1_45796852_G_C   0.019154034
chr19_9018540_A_G   
chr19_9002576_T_C   
chr1_45797487_A_G   0.012981216
chr1_45797153_A_T   0.010129176
chr1_45797750_C_T   0.024949931

私はすでに言及しましたawk - 2つのファイルの2つの列を比較し、共通の行を印刷します。ただし、一致するもののみを提供します。

答え1

最初に読み、fileB.txt最初のフィールドをキーにし、2番目のフィールドを配列の値にしFNR>1(を使用してヘッダー行をスキップします)。NRとFNRとは何ですか? "NR==FNR" とはどういう意味ですか?)。

次に、を読み、fileA.txt最初の行のヘッダー、最初のフィールド、配列の対応する要素(存在する場合)を印刷します。

awk '
    FNR==NR && FNR>1{a[$1]=$2}
    NR!=FNR{
        if(FNR>1){print $1,a[$1]}
        else{print "id", "freq.var"}
    }
' OFS="\t" fileB.txt fileA.txt

OFS="\t"出力フィールド区切り記号をタブに設定します。ファイルはタブで区切られているため、出力ファイルもタブで区切る必要があるとします。

整列のためにパイプで接続できますcolumn -t

答え2

元のソート順を維持する必要がない場合は、次のものを使用できますjoin

$ join -a1 -j1 -t$'\t' <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort)
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G

またはヘッダーを維持してください。

$ ( printf 'id\tfreq.var\n'; join -t$'\t' -a1 -j1 <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort))
id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G

そしてかわいい指紋もあります:

$ ( printf '%-20s\t%s\n' "id" "freq_var"; join -t$'\t' -a1 -j1 <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort))
id                      freq_var
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G

答え3

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
    map[(NR>1 ? $1 : "id")] = $2
    next
}
{ print $1, map[$1] }
$ awk -f tst.awk fileB fileA
id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796854_C_T   0.015872901
chr1_45797174_T_A
chr1_45796852_G_C   0.019154034
chr19_9018540_A_G
chr19_9002576_T_C
chr1_45797487_A_G   0.012981216
chr1_45797153_A_T   0.010129176
chr1_45797750_C_T   0.024949931

答え4

GNU sed拡張正規表現モードがオンになっており-E、自動印刷されません-n。まず、fileBを読み取り、予約済みスペースに保存します。次に、ファイルAの各行を比較して予約済みであることを確認します。

sed -En '
  1{
    s/^\S+/id/
    :filea
      H;n
    /\t/b filea
    x;s/$/\n/;x
  }
  G
  s/^([^\n]+)\n.*\n(\1\t[^\n]*)\n.*/\2/p;t
  s/\n.*/\t/p
' fileB.txt fileA.txt

結果:

id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796854_C_T   0.015872901
chr1_45797174_T_A   
chr1_45796852_G_C   0.019154034
chr19_9018540_A_G   
chr19_9002576_T_C   
chr1_45797487_A_G   0.012981216
chr1_45797153_A_T   0.010129176
chr1_45797750_C_T   0.024949931

関連情報