【问题标题】:Initialize an Array inside AWK Command and use the Array to Print using AWK在 AWK 命令中初始化一个数组并使用 AWK 使用该数组进行打印
【发布时间】:2018-02-09 06:19:17
【问题描述】:

我正在尝试比较 2 个文件数据并打印出来。

我的主要目标是在同一个 awk 语句中初始化一个包含一些值的 araay,并将其用于某些打印目的。

下面是我正在使用的命令,我觉得它看起来像一些语法错误。

请在 AWK 部分提供帮助,我应该如何定义数组以及我如何在其中使用它。

命令尝试 -

paste -d "|" filedata.txt tabdata.txt | awk -F '|' '{array=("RE_LOG_ID" "FILE_RUN_ID" "FH_RECORDTYPE" "FILECATEGORY")}' '{c=NF/2;for(i=1;i<=c;i++)if($i!=$(i+c))printf "%s|%s|%s|%s\n",$1,${array[i]},$i,$(i+c)}'

示例输入文件

文件数据.txt

A|1|2|3
B|2|3|4

tabdata.txt

A|1|4|3
B|2|3|7

所以我想要的输出是 . -

A|FH_RECORDTYPE|2|4
B|FILECATEGORY|4|7

输出包含差异 -

PRIMARYKEY|COLUMNNAME|FILE1DATA|FILE2DATA

我希望在 AWK 中将 Array 初始化为 array=("RE_LOG_ID" "FILE_RUN_ID" "FH_RECORDTYPE" "FILECATEGORY") 并对应列名

从数组条件中获取列名将是当 ($i!=$(i+c)) 时,无论第“i”个位置不匹配,我将打印数组中的第“i”个元素。

如果我从命令中删除数组部分,则查找差异部分的工作非常完美,但我的问题是我想初始化一个包含列名的数组并在 awk 语句中打印它。

只是我需要帮助如何将数组部分合并到 AWK 中。

【问题讨论】:

  • 请在您的帖子中的代码标签中发布示例 Input_file 和预期的示例输出,然后让我们知道。
  • 使用示例更新
  • Samrat,请更清楚地解释一下,比如FH_RECORDTYPE 是如何输出的?请为您的问题添加更多详细信息。
  • @RavinderSingh13 -- 如果你看到我的命令尝试了那些是我想要的数组元素..
  • 是的,我知道您想在特定条件下插入一些文本,但您的条件不清楚。请花点时间重新定义您的帖子。

标签: bash awk


【解决方案1】:

不幸的是,AWK 中的数组无法按预期分配。作为替代方案,您可以使用split 函数,例如:

split("RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY", array, " ")

(需要可选的“ ”,因为 FS 已被覆盖。)
然后您的命令将如下所示:

paste -d "|" filedata.txt tabdata.txt | awk -F '|' '
BEGIN {split("RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY", array, " ")}
{
    c= NF/2;
    for(i=1; i<=c; i++)
        if ($i != $(i+c))
            printf "%s|%s|%s|%s\n", $1, array[i], $i, $(i+c);
}'

【讨论】:

  • 上述工作完全符合预期,但我想问一个额外的差异。例如,让我在如下变量中有列名“RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY” - colnames="RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY" ,现在我试图用看起来不起作用的变量替换命令,你可以添加请您对此发表评论-
  • 粘贴 -d "|"新文件1.dat 新文件2.dat | awk -F '|' ' 开始 {split("$colnames",array,"")} { c= NF/2; for(i=1; i
  • 有几种方法可以将 shell 变量传递给 AWK 脚本。一个是您尝试的“变量扩展”。在这种情况下,我们需要用双引号而不是单引号来引用整个脚本块以启用变量扩展。然后我们需要添加反斜杠来转义在双引号中具有特殊含义的字符。
  • colnames="RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY" paste -d "|" newfile1.dat newfile2.dat | awk -F '|' " BEGIN {split(\"$colnames\",array,\" \")} { c= NF/2; for(i=1; i&lt;=c; i++) if (\$i != \$(i+c)) printf \"%s|%s|%s|%s\n\", \$1, array[i], \$i, \$(i+c); }" 在我看来我不推荐它,因为转义很乱。
  • 另一个选项是使用 AWK 的 -v 选项:colnames="RE_LOG_ID FILE_RUN_ID FH_RECORDTYPE FILECATEGORY" paste -d "|" newfile1.dat newfile2.dat | awk -F '|' -v colnames=$colnames ' BEGIN {split(colnames,array," ")} { c= NF/2; for(i=1; i&lt;=c; i++) if ($i != $(i+c)) printf "%s|%s|%s|%s\n", $1, array[i], $i, $(i+c); }'
猜你喜欢
  • 1970-01-01
  • 2012-12-13
  • 2014-08-13
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 2018-01-16
  • 2019-02-20
相关资源
最近更新 更多