2番目のファイルキーに基づいて最初の列を使用して最初のファイルをソートするソリューションを見つけようとしています。
最初のファイルの例(file1.csv)
COLUMN1 COlUMN2
apple fruit
dog animal
cat animal
cow animal
2番目のファイルの例(sort_keys.txt)
cat
dog
apple
cow
期待される出力(sorted.txt)
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
これまで役立つ sort コマンドと awk コマンドを見つけましたが、うまくいくコードはありません。
$> awk 'NR==FNR{o[FNR]=$1; next} {t[$1]=$0} END{for(x=1; x<=FNR; x++){y=o[x]; print t[y]}}' sort_key.txt file1.csv
しかし、コマンドが期待どおりに機能しないため、専門家のアドバイスが必要です。 PS 私はLinuxコマンドの知識を持っていますが、これは非常に具体的であり、実装方法を知りません。
どんな助けやアドバイスにも感謝します。
答え1
$ awk 'NR==1; NR==FNR{a[$1]=$2; next} {print $1, a[$1]}' file1 sort_keys.txt
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
答え2
GNU awk(別名)があれば、カスタムgawk
ソート機能を定義して使用できます。
たとえば、PROCINFO
GNU awk> 4.0の配列反復関数を想定すると、次のようになります。
$ gawk '
function mysort(ia,va,ib,vb){return o[ia] - o[ib]}
NR==FNR{o[$1]=FNR; next} # map keys to numerical order
FNR==1{print; next} # print + skip the header line
{a[$1]=$0}
END{
PROCINFO["sorted_in"] = "mysort"
for(i in a) print a[i]
}
' sort_key.txt file1.csv
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
(以前のGNU awksではasorti
。
答え3
データがそれほど大きくない場合、二次複雑さを持つ簡単なソリューションは次のとおりです。
cat sort_keys.txt | while read key ; do egrep "^$key " file1.csv ; done
ヘッダーを追加/削除するには、head
必要に応じてコマンドを追加します。tail
答え4
あなたはそれを使用することができますjoin
。からman join
:
同じ結合フィールドを持つ各入力行ペアに対して、標準出力に1行を書き込みます。デフォルトの結合フィールドは最初にスペースで区切られます。
最初の行はソートしてはいけません。
全長DR:
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
仕事をします。
説明する
基本的に我々は:
- file1.csv の最初の行を抽出します。
- 最初のフィールドで sort_keys を使用して file1.csv の残りの部分をリンクします。
- sort_keys の順序で結果を並べ替える
また、join
ファイルを並べ替える必要があります。
これは私たちを次に導きます:
- 最初の入力としてsort_keysファイル(前のフィールドで)に番号を付け(最後にこの元の順序を使用できるように)、2番目のフィールドを並べ替えます。
cat -n sort_keys.txt | sort -k 2
3 apple
1 cat
4 cow
2 dog
- 2番目の入力としてcsvファイルをインポートし、最初の行をスキップして最初のフィールドでソートします。
tail -n +2 file1.csv | sort
apple fruit
cat animal
cow animal
dog animal
- その後、最初のプロセスの2番目のフィールド()を使用して
-1 2
それらを結合できます。
join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort)
apple 3 fruit
cat 1 animal
cow 4 animal
dog 2 animal
- これで、結合結果を2番目のフィールドの数字で並べ替えることができます(sort_keysが9項目を超える場合)、最初と3番目のフィールドのみを保持します。
「... | sort -n -k 2 '{$ 1、$ 3印刷}」
cat animal
dog animal
apple fruit
cow animal
- 最後に、これをfile1.csvの最初の行の前に追加します。
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
さらに進む
実際のデータに応じて、フィールド番号とフィールド区切り記号を調整する必要があります。
キーがsort_keysにないデータ行、またはsort_keysにそのデータ行がない行を保持したい場合もあります(-a
結合オプションを参照)。
自由に試してみてくださいjoin
!