【问题标题】:Using awk, combine multiple key-data in one file with multiple key-values from a second file?使用awk,将一个文件中的多个键数据与第二个文件中的多个键值结合起来?
【发布时间】:2017-06-01 00:20:11
【问题描述】:

data.txt(数据;键;数据;键):

Data1;Key1;DataA;KeyA
Data2;Key2;DataB;KeyB
Data3;Key3;DataC;KeyA
Data4;Key2;DataC;KeyB
Data3;Key1;DataB;KeyA
Data2;Key5;DataA;KeyB

keys.txt(键;值;键;值;键;值):

Key1;10;keyA;100;keyB;1000;
Key2;20;keyA;200;keyB;2000;
Key3;30;keyA;300;keyB;3000;
Key4;30;keyA;400;keyB;4000;

因此,与 Key1 位于同一行的 KeyA 给出 KeyA=100。 同样,与 Key2 位于同一行的 KeyA 给出KeyA=200。 KeyB 的类似过程。

输出(将keys.txt中适当的两个值附加到data.txt的每一行):

Data1;Key1;DataA;KeyA;10;100
Data2;Key2;DataB;KeyB;20;2000
Data3;Key3;DataC;KeyA;30;300
Data4;Key2;DataC;KeyB;20;2000
Data3;Key1;DataB;KeyA;10;100
Data2;Key5;DataA;KeyB;-;-

例如,data.txt 中的第一行包含 Key1 和 KeyA,因此在 keys.txt 中找到包含 key1 和 附加其对应的值,然后附加 KeyA 或 KeyB,在这种情况下,KeyA 为 100。因此,keys.txt 中第一行的 KeyB 不是 用于输出第一行中的任何内容。

data.txt 中的最后一行包含 Key5,但 keys.txt 中没有 Key5,因此附加一个默认值;-;-

【问题讨论】:

  • 糟糕,您忘记发布代码了! StackOverflow 旨在帮助人们修复他们的代码。这不是免费的编码服务。任何代码都比没有代码好。即使您不知道如何编写它,元代码甚至会展示您认为程序应该如何工作。请查看stackoverflow.com/help/how-to-ask 以获取有关改进此问题的提示。

标签: awk multiple-columns key-value substitution


【解决方案1】:

将此保存到名为program的文件中:

BEGIN { FS=";"; }
NR==FNR {
    data[$1] = $2;
    data[$1, toupper($3)] = $4;
    data[$1, toupper($5)] = $6;
    next;
}
{
    one = data[$2];
    two = data[$2, toupper($4)];
    print $0 ";" (one ? one : "-") ";" (two ? two : "-");
}

然后,拨打awk -f program keys.txt data.txt

【讨论】:

  • 纯 awk 解决方案很好,但是,对我来说它不起作用?:./b:第 1 行:意外标记附近的语法错误 }' ./b: line 1: BEGIN { FS=";"; }'
  • @Markus awk 的哪个版本?
  • GNU Awk 4.0.1 顺便说一句,我看不到输入文件(data.txt 和 keys.txt)在您的解决方案中的位置?
  • @Markus 抱歉,我认为这很明显:awk -f program keys.txt data.txt
  • Markus - 您已经问了多个 awk 问题并收到了多个答案,但您不知道如何使用发布的脚本并希望在答案中包含命令,以便您可以复制/粘贴它??? Michael - one = data[$2];...print $0 ";" (one ? one : "-")...data 中创建元素,因此使用的内存比必要的多,如果/当 data[$2] 的值在数值上为零时,它将失败。你应该改用one = ($2 in data ? data[$2] : "-");...print $0 ";" one ...
【解决方案2】:

简单的脚本可以满足您的要求。使用awk解析提取data.txt中的key。您可能会在keys.txt中找到对应的键值。

#!/bin/bash                                                                                                                                                                                                  

while read i; do

  echo $i | awk '{printf "%s;",$1}'
  key_no=$(echo $i | awk -F';' '{print $2}')
  key_a_b=$(echo $i | awk -F';' '{print $4}')

  grep $key_no keys.txt | awk -v key="$key_a_b" -F';' '{
      if (key=="KeyA") {printf "%d;%d\n",$2,$4}
      if (key=="KeyB") {printf "%d;%d\n",$2,$6}
    }'

  [ ${PIPESTATUS[0]} -ne 0 ] && echo "-;-"

done < data.txt

【讨论】:

猜你喜欢
  • 2022-10-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2021-01-27
  • 2021-11-21
  • 2014-12-01
  • 2018-09-26
  • 2016-02-05
相关资源
最近更新 更多