【问题标题】:Conditional vlookup in bash with awk or sed?使用awk或sed在bash中进行条件查找?
【发布时间】:2018-09-19 00:48:28
【问题描述】:

我有这两个文件(都有标题),两个文件的每一行都以相同格式的第一列上的日期开头。分隔符是分号。

在第一个文件的第 9 列,我只能有那些 id:UK 或 JPN 或 EUR。

我需要将 file1 与来自 file2 的 intel 与相应的日期 intel 聚合起来。

当然,我可以尝试使用 bash 脚本和“for”循环来实现,但我确信资源方面,使用 awk 或其他 bash 命令会更好......如果可能的话!

提前感谢您的任何提示。

ps:我尝试适配这个方法没有成功:https://unix.stackexchange.com/questions/428861/vlookup-equivalent-in-awk-scripting

第一个文件:

Date;$2;$3;$4;$5;$6;$7;$8;Id
2018-01-01;              ;UK
2018-01-02;              ;JPN
2018-01-03;              ;EUR
2018-01-04;              ;JPN

第二个文件:

Date;UKDIR;JPNDIR;EURDIR

2018-01-01;1;2;3           
2018-01-02;4;5;6              
2018-01-03;7;8;9
2018-01-04;11;10;12

预期回报

Date;$2;$3;$4;$5;$6;$7;$8;Id  ;Intel
2018-01-01;              ;UK  ;1
2018-01-02;              ;JPN ;5
2018-01-03;              ;EUR ;9
2018-01-04;              ;JPN ;10

【问题讨论】:

  • 最后一条记录应该是2018-01-04; ;JPN ;10吧?
  • 没错!对不起!

标签: bash awk


【解决方案1】:

你可以使用这个awk:

awk -F';' -v OFS='; ' 'NR==1 { for (i=2; i<=NF; i++) h[i]=$i; next }
   FNR==NR { for (i=2; i<=NF; i++) a[$1,h[i]]=$i; next }
   FNR==1 { print $0, "Intel"; next }
   { print $0, a[$1,$NF "DIR"] }' file2 file1

Date;$2;$3;$4;$5;$6;$7;$8;Id; Intel
2018-01-01;              ;UK; 1
2018-01-02;              ;JPN; 5
2018-01-03;              ;EUR; 9
2018-01-04;              ;JPN; 10

【讨论】:

  • 谢谢,但 OP 必须先确认 :)
【解决方案2】:

请您尝试关注一下。

awk '
BEGIN{
  count=count1=1
  FS=OFS=";"
}
FNR!=NR && FNR==1{
  print $0 OFS "Intel"
}
FNR==NR && /^[0-9]/{
  a[$1]=$(++count)
  count=count==4?1:count
  next
}
NF && /^[0-9]/{
  print $0 OFS a[$1]
  count1=count1==4?1:count1
}
' second_file  first_file

输出如下。

Date;$2;$3;$4;$5;$6;$7;$8;Id;Intel
2018-01-01;              ;UK;1
2018-01-02;              ;JPN;5
2018-01-03;              ;EUR;9
2018-01-04;              ;JPN;11

【讨论】:

    【解决方案3】:
    $ cat tst.awk
    BEGIN { FS=OFS=";" }
    NR==FNR {
        if (NR == 1) {
            for (fldNr=2; fldNr<=NF; fldNr++) {
                fldName = $fldNr
                sub(/DIR/,"",fldName)
                fldNr2name[fldNr] = fldName
            }
        }
        else {
            for (fldNr=2; fldNr<=NF; fldNr++) {
                fldName = fldNr2name[fldNr]
                dateFldName2val[$1,fldName] = $fldNr
            }
        }
        next
    }
    {
        print $0, (FNR>1 ? dateFldName2val[$1,$NF] : "Intel")
    }
    
    $ awk -f tst.awk file2 file1
    Date;$2;$3;$4;$5;$6;$7;$8;Id;Intel
    2018-01-01;              ;UK;1
    2018-01-02;              ;JPN;5
    2018-01-03;              ;EUR;9
    2018-01-04;              ;JPN;10
    

    【讨论】:

      猜你喜欢
      • 2019-02-20
      • 2020-02-03
      • 1970-01-01
      • 2013-11-09
      • 2017-11-11
      • 1970-01-01
      • 2020-09-27
      • 2011-04-07
      • 1970-01-01
      相关资源
      最近更新 更多