Unixの列値に基づいて、特定のソート順でFile1、File2の行をFile3に追加します。

Unixの列値に基づいて、特定のソート順でFile1、File2の行をFile3に追加します。

一週間オンラインで検索しましたが、私のシナリオに合った解決策が見つからないようです。 2つのファイルがあります。

File1 には多くの列が含まれていますが、最後の列は参照番号です。ドライバファイルとして使用されます。

ファイル1の内容:

file1abc|file1abc|file1123|9999999    
file1def|file1def|file1456|8888888

File2にも多くの列が含まれていますが、参照番号が重複しており、必須のソートフィールドがあります。

ファイル2コンテンツ

file2xyz|file2xyz|file2987|sort1|9999999
file2qrs|file2qrs|file2765|sort2|8888888
file2efg|file2efg|file2555|sort3|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2xyz|file2xyz|file2987|sort1|8888888

希望の結果を出力します。

ファイル1行が最初の行になり、その後に参照番号が一致し、#列に基づいてソートされるファイル2行が続きます。

出力には以下が含まれます。

file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2efg|file2efg|file2555|sort2|9999999
file2tuv|file2tuv|file2666|sort3|9999999
file1def|file1def|file1456|8888888
file2qrs|file2qrs|file2765|sort1|8888888
file2xyz|file2xyz|file2987|sort2|8888888

どんな助けやアドバイスにも感謝します。

ベストアンサー1

最新バージョンのGNU awkがある場合は、2D配列を使用し、グローバルPROCINFOに配列巡回を設定して使用してください。ステルing(つまり、語彙)値産業前に昇順終了順序:

gawk '
  BEGIN {FS = "|"; PROCINFO["sorted_in"] = "@ind_str_asc"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; for(i in a[$NF]) print a[$NF][i]}
' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

以前のGNU awkの場合は、次のようにしてasorti同じ結果を得ることができます。

gawk '
  BEGIN{FS="|"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; n = asorti(a[$NF],dst,"@ind_str_asc"); for(i=1;i<=n;i++) print a[$NF][dst[i]]}
' File2 File1

ソートしたい場合数値的に(NF-1)最初のフィールドの一部の部分文字列に基づいて@ind_str_asc2番目の配列インデックスに変更し、@ind_num_ascそれを$(NF-1)適切に前処理された値に置き換えることができます。

substr($(NF-1),5)

または正規表現を使用してください(より複雑なキー抽出のため)

gensub(/[^0-9]*([0-9]+)$/,"\\1","1",$(NF-1))

他のawkの場合は、1D配列と外部アライメントを使用できます。

mawk '
  BEGIN {FS="|"; cmd = "sort -t \| -k4"}
  NR==FNR {a[$NF] = a[$NF] (a[$NF]=="" ? "" : ORS) $0; next}
  {print; print a[$NF] | cmd; close(cmd)}' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

ここで、ソートオプションは外部機能でサポートされているオプションに制限されていますsortcmd = "sort -t \| -k4.5,4n"4番目のフィールドの5番目の文字に基づいて数値順に並べ替えます。

おすすめ記事