vlookupにawkを使用する方法は?

vlookupにawkを使用する方法は?

フィールドには次のファイルがあります。ID指定する親ID親の指定。ファイルの内容は次のとおりです。

A1  M.D-Sales    0    UmbrellaCorp
a1  Sr.Sales    A1
b1  Sr.R&D      B1
b2  Jr.SR&D     B1
a2  Jr.Sales    A1
B1  M.D-R&D      0    UmbrellaCorp

欲しい親の指定4番目の列がない行の場合、これは基本的に次のことを意味します。

  • 各行を読む
  • 得る親ID3列目から始まる
  • 最初の列の値と一致させます。
  • 子の前の4番目の列4に挿入します。

結果は以下の通りです。

A1  M.D-Sales    0  UmbrellaCorp
a1  Sr.Sales    A1  M.D-Sales
b1  Sr.R&D      B1  M.D-R&D
b2  Jr.SR&D     B1  M.D-R&D
a2  Jr.Sales    A1  M.D-Sales
B1  M.D-R&D      0  UmbrellaCorp

Excelを使用して同じことを行う方法を知っていますが、vlookupスクリプトを使用する必要があります。

ベストアンサー1

最終的な回答は、より多くの説明とともに以下に提供され、関連する例の入力/出力で更新されました。

欠落している値を入力することは、awkで2段階のアプローチを実行するよりも効率的で、メモリを使い果たすようにデータを最初にソートし、読みやすくするために最終出力が入力よりも優れています。

$ cat tst.sh
#!/usr/bin/env bash

awk '
    BEGIN { FS=OFS="\t" }
    { print (NR>1), ($4=="" ? $3 : $1), $4, $1, NR, $0 }
' "${@:--}" |
sort -t$'\t' -k1,1n -k2,2 -k3,3r -k4,4 -k5,5n |
cut -f6- |
awk '
    BEGIN { FS=OFS="\t" }
    $4 != "" { d = $2 }
    $4 == "" { $4 = d }
    { print }
'

$ ./tst.sh file | column -s$'\t' -t
ID  Designation  ParentID  ParentDesignation
A1  M.D-Sales    0         UmbrellaCorp
a1  Sr.Sales     A1        M.D-Sales
a2  Jr.Sales     A1        M.D-Sales
B1  M.D-R&D      0         UmbrellaCorp
b1  Sr.R&D       B1        M.D-R&D
b2  Jr.SR&D      B1        M.D-R&D

awkへの最初の呼び出しは、次のようにソートできるように入力を変更します。

  1. (NR>1)=ソート後にヘッダー行が最初に残っていることを確認するためのヘッダーかどうか0または1のインジケーター、
  2. ($4=="" ? $3 : $1)=関連行をグループ化するために使用される各行のIDまたはParentID
  3. $4= ParentDesignation - ParentDesignationを持つ行が同じID / ParentIDを持たない行の前に配置されるようにソートできます。
  4. $1= ID、したがって、ID ごとにアルファベット順にサブアイテムを並べ替えることができます。
  5. NR= したがって、他のすべてが共通であれば、入力に現れる順序で行を印刷することができます(この場合、各IDは一意のように見えるため、必要ではありませんが、他の同様の場合は問題ありません)。

sortその後、上記のフィールドを渡してから削除デコレータを使用して、実際に入力した最終スクリプトに渡します。cutawk$4

これらのステップがどのような役割を果たしているかわからない場合は、各ステップを|一度に1つずつ変更することで、各ステップで何が起こっているのかを確認できます。| cat; exit


前の答え:

以下の説明を見ると、親(存在する場合)がデータの常に子の前に表示されると仮定すると、これはおそらく望むものです。

$ cat tst.awk
BEGIN { FS=OFS="\t" }
$4 != "" {
    id2des[$1] = $2
}
$4 == "" {
    $4 = id2des[$3]
}
{ print }

$ awk -f tst.awk file
ID      Designation     ParentID        ParentDesignation
A1      M.D-Sales       0       UmbrellaCorp
a1      Sr.Sales        A1      M.D-Sales
a2      Jr.Sales        A1      M.D-Sales
B1      M.D-R&D 0       UmbrellaCorp
b1      Sr.R&D  B1      M.D-R&D
b2      Jr.SR&D B1      M.D-R&D

元の答え:

すべての情報を含む親行と$ 4が欠落している子行があるように見えるため、問題は実際に指定したものよりも単純に見えます。この場合、何も見つける必要はありません。必要なものは次のとおりです。 :

$ awk 'BEGIN{FS=OFS="\t"} $4!=""{d=$2} $4==""{$4=d} 1' file
ID      Designation     ParentID        ParentDesignation
A1      M.D-Sales       0       UmbrellaCorp
a1      Sr.Sales        A1      M.D-Sales
a2      Jr.Sales        A1      M.D-Sales
B1      M.D-R&D 0       UmbrellaCorp
b1      Sr.R&D  B1      M.D-R&D
b2      Jr.SR&D B1      M.D-R&D

$ awk 'BEGIN{FS=OFS="\t"} $4!=""{d=$2} $4==""{$4=d} 1' file | column -s$'\t' -t
ID  Designation  ParentID  ParentDesignation
A1  M.D-Sales    0         UmbrellaCorp
a1  Sr.Sales     A1        M.D-Sales
a2  Jr.Sales     A1        M.D-Sales
B1  M.D-R&D      0         UmbrellaCorp
b1  Sr.R&D       B1        M.D-R&D
b2  Jr.SR&D      B1        M.D-R&D

おすすめ記事