同じフィールドのソート値に基づいて2つのソートされたファイルをマージします。

同じフィールドのソート値に基づいて2つのソートされたファイルをマージします。

長さは必ずしも同じである必要はありませんが、同じデータフィールドと同じヘッダーを使用して、特定の列の順序に従って保持されるヘッダーの後に始まり、2つのソートされたファイルの行をマージしたいと思います。たとえば、ファイル1は次のようになります。

header 1
header 2
header 3

cat    4    aa
dog    5    ab
ostrich    10    cd
fish    13    cc

ファイル2は次のようになります。

header 1
header 2
header 3

lemur    3    dd
alligator    4    ca
lemming    16    ad

1) 同じヘッダーを保持したいのですが、2) 列 2 に基づいて次の行をソートしたいと思います。私が望む出力は次のとおりです。

header 1
header 2
header 3

lemur    3    dd
cat    4    aa
alligator     4    ca
dog    5    ab
ostrich    10    cd
fish    13    cc
lemming     16    ad

探していますが、awkまたはを使用してこの状況の解決策を見つけることはできませんjoin

答え1

awkそしてjoin間違ったツールです。

sed '/^$/q' file1; sort -snmk2,2 <(sed '1,/^$/d' file1) <(sed '1,/^$/d' file2)

答え2

最新(バージョン> 4.0)GNU awkを使用するとできます

awk '
  FNR>4 {a[$0]=$2; next}; 
  NR==FNR; 
  END {
    PROCINFO["sorted_in"] = "@val_num_asc"; 
    for (i in a) print i;
  }
' file1 file2

説明する:

  • FNR>4 {a[$0]=$2; next};ヘッダー以外の行のソートフィールド配列の作成
  • NR==FNR;最初のファイルに対してのみTRUEを評価し、reachに対してのみ評価して、FNR>4最初のファイルに対してヘッダー行が印刷されるようにします。
  • PROCINFO["sorted_in"] = "@val_num_asc"値に基づいて配列を並べ替えます(たとえば、保存フィールド$ 2)。
  • for (i in a) print i印刷索引ソートされた配列(ヘッダー以外の行が格納されている)

テスト

$ awk 'FNR>4 {a[$0]=$2; next}; NR==FNR; END {PROCINFO["sorted_in"] = "@val_num_asc"; for (i in a) print i;}' file1 file2
header 1
header 2
header 3

lemur    3    dd
cat    4    aa
alligator    4    ca
dog    5    ab
ostrich    10    cd
fish    13    cc
lemming    16    ad

答え3

プロセス置換と一緒にシェル(ksh93、、、...)を使用しますbash(プロセス置換を持たない選択肢については最後を参照)。

cat <( head -n 3 file1 ) \
    <( sort -k2,2n <( tail -n +4 file1 | tr -s ' ' '\t' ) \
                   <( tail -n +4 file2 | tr -s ' ' '\t' ) | uniq )

結果は次のとおりです。

header 1
header 2
header 3

lemur   3       dd
alligator       4       ca
cat     4       aa
dog     5       ab
ostrich 10      cd
fish    13      cc
lemming 16      ad

このコマンドは、ヘッダー行をfile1ソート操作の結果に関連付けます。ソートは一部の入力の2番目のフィールドで数字で行われ、重複した行(ワニ、キツネザル、レミング)はuniq結果から削除されます。

file1並べ替える入力は、連続した空白を単一のタブに置き換えるために渡された無題file2の内容ですtr(例データには列間の空白の数が不均一です)。

結果はタブで区切られます。


同じツールを使用する同等の方法:

cat <( head -n 3 file1 ) \
    <( sort -k2,2n <( cat <( tail -n +4 file1 ) \
                          <( tail -n +4 file2 ) | tr -s ' ' '\t' ) | uniq )

catsとプロセスを置き換えることなく:

{ head -n 3 file1;
    { tail -n +4 file1; tail -n +4 file2; } | tr -s ' ' '\t' | sort -k2,2n | uniq; }

関連情報