長さは必ずしも同じである必要はありませんが、同じデータフィールドと同じヘッダーを使用して、特定の列の順序に従って保持されるヘッダーの後に始まり、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 )
cat
sとプロセスを置き換えることなく:
{ head -n 3 file1;
{ tail -n +4 file1; tail -n +4 file2; } | tr -s ' ' '\t' | sort -k2,2n | uniq; }