列の一致と置換

列の一致と置換

スペースで区切られたフィールドを持つ2つの非常に大きなテキストファイルがあります。

ファイル1

527858  51  2   27.92464882 8.63E-07
570289  82  2   30.12532071 2.87E-07
571034  90  2   29.26089611 4.43E-07
571033  90  2   28.56723908 6.26E-07
452403  104 2   28.27577506 7.24E-07
351390  100 2   28.16226794 7.67E-07
527858  50  2   27.92464882 8.63E-07

ファイル2

527858  rs435           
570289  rs564           
571034  rs654           
571033  rs345           
452403  rs665           
351390  rs787           
527858  rs435           

出力:

rs435   51  2   27.92464882 8.63E-07
rs564   82  2   30.12532071 2.87E-07
rs654   90  2   29.26089611 4.43E-07
rs345   90  2   28.56723908 6.26E-07
rs665   104 2   28.27577506 7.24E-07
rs787   100 2   28.16226794 7.67E-07
rs435   50  2   27.92464882 8.63E-07

file1とfile2の最初の列を比較し、file1の最初の列をfile2の2番目の列の名前置き換えます。

答え1

頑張ります

awk 'FNR==NR { F2[$1]=$2 ; next } $1 in F2 {$1 = F2[$1] ; print } ' File2 File1

どこ

  • FNR==NR { F2[$1]=$2 ; next }File1に値を保存します。
  • $1 = F2[$1]キーの交換

答え2

これはawk、と同じ基本的な考えです。アケマの答え、Perlで実装:

$ perl -lane '$#F>1?print"$l{$F[0]} @F[1..$#F]":($l{$F[0]}=$F[1])' file2 file1
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs654 90 2 29.26089611 4.43E-07
rs345 90 2 28.56723908 6.26E-07
rs665 104 2 28.27577506 7.24E-07
rs787 100 2 28.16226794 7.67E-07
rs435 50 2 27.92464882 8.63E-07

説明する

  • -lane-l各呼び出しに改行文字を追加し、各print入力行から末尾の改行文字を削除します。-amakeが実行するperl作業は次のとおりですawk。各入力行を自動的に配列に分割します@F。したがって、最初のフィールドは$F[0]、2番目のフィールド$F[1]などになります。-nPerlに入力ファイルを1行ずつ読み、与えられたスクリプトを-e各ファイルに適用するように指示します。

  • $#F>1? ... : ...:C スタイルの条件付き演算子です。一般的な形式は次のとおりですcondition ? foo : barconditiontrueの場合はdo foo、trueではないdo bar。これは$#F配列の配列インデックスの数です。配列@Fはで始まるので、値は02つの要素を1含む配列を表します。print ...番目のブロック(下記参照)が実行されますfile1

  • ($l{$F[0]}=$F[1]):これは、file2の各行、3つ未満のフィールドを持つ各行に対して実行されます。%lキーが最初の数値フィールドfile2で、値が関連するrsIDのハッシュを入力します。
  • print"$l{$F[0]} @F[1..$#F]"%l:最初のフィールド()のハッシュのrsIDを$l{$F[0]}スペースで印刷し、行($F[1..$#F])の残りのフィールドを印刷します。

個人的には、私はおそらくそのawkソリューションを使用するか、最悪の場合はperl私が提供したソリューションを使用します。なぜなら、ファイルをソートする必要がないからです。ただし、タグ付けしたので、joinツールを使用する方法は次のとおりです。

$ join -o 2.2 1.2 1.3 1.4 1.5 <(sort file1) <(sort file2)
rs787 100 2 28.16226794 7.67E-07
rs665 104 2 28.27577506 7.24E-07
rs435 50 2 27.92464882 8.63E-07
rs435 50 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs345 90 2 28.56723908 6.26E-07
rs654 90 2 29.26089611 4.43E-07

関連情報