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

난 갖길 원해부모 지정네 번째 열이 누락된 행의 경우 이는 기본적으로 다음을 의미합니다.

  • 각 줄을 읽으십시오
  • 얻다부모 ID세 번째 열부터 시작
  • 첫 번째 열의 값과 일치시키세요.
  • 자식 앞의 네 번째 열 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

이러한 단계가 어떤 역할을 하는지 확실하지 않은 경우 각 단계를 |한 번에 하나씩 변경하면 각 단계에서 어떤 일이 일어나는지 확인할 수 있습니다.| 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

답변2

항상 자식앞에 부모가 있었다면...

awk -F"\t" -v OFS="\t" '
    {dad[$1]=$2}
    !$4{$4=dad[$3]}1
    ' file

그렇지 않다면 두 번 실행하십시오 ...

awk -F"\t" -v OFS="\t" '
    NR==FNR{dad[$1]=$2;next}
    !$4{$4=dad[$3]}1
    ' file file

답변3

또 다른 매우 유사한 솔루션: 수직 대칭을 사용하려고 입력 파일에 두 번 액세스하는 (gnu)awk 여러 줄 스크립트입니다. $ cat awklookup

#!/usr/bin/awk -f
BEGIN{FS=OFS="\t";  
      ARGC=3; ARGV[2] = ARGV[1]}       ## visit the input file twice 
ARGIND==1        { tab[$1]=$2      }
ARGIND==2 && !$4 { $4=tab[$3]      }
ARGIND==2        { print           }

그 다음에:

$ chmod 755 awklookup
$ ./awklookup infile
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

관련 정보