使用AWK命令初始化一个数组并利用该数组使用AWK打印

3

我是一名有用的助手,可以为您翻译文本。

我正在尝试比较两个文件的数据,并打印其中某些内容。

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

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

请在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)}'

SAMPLE INPUT FILE

filedata.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=("RE_LOG_ID" "FILE_RUN_ID" "FH_RECORDTYPE" "FILECATEGORY"),并与列名相对应。

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

如果我从命令中删除数组部分,则查找差异部分运行得非常完美,但我的要求是在awk语句中初始化包含列名的数组并打印它。

我只需要知道如何在AWK中加入数组部分即可。


1
请在您的帖子中以代码标签形式发布示例输入文件和期望的示例输出。 - RavinderSingh13
已更新,附带示例 - Samrat Saha
Samrat,请更清楚地解释一下,例如 FH_RECORDTYPE 是如何出现在输出中的?请在您的问题中添加更多细节。 - RavinderSingh13
@RavinderSingh13 -- 如果你看到我的命令尝试了那些数组元素,那就是我想要的。 - Samrat Saha
是的,我明白你想在特定条件下插入一些文本,但你的条件不清楚。请花些时间重新定义你的帖子。 - RavinderSingh13
@RavinderSingh13 插入的条件是当 ($i!=$(i+c)),无论哪个“i”位置不匹配,我都会打印出数组中的第“i”个元素。 - Samrat Saha
1个回答

2

很遗憾,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",现在我试图用该变量替换命令,但似乎不起作用,请您发表一下意见。 - Samrat Saha
paste -d "|" newfile1.dat newfile2.dat | awk -F '|' ' BEGIN {split("$colnames",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); }' - Samrat Saha
有几种方法可以将shell变量传递给AWK脚本。 其中一种是“变量扩展”,就像你正在尝试的那样。在这种情况下,我们需要用双引号而不是单引号引用整个脚本块以启用变量扩展。 然后,我们需要添加反斜杠来转义双引号内具有特殊含义的字符。 - tshiono
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<=c; i++) if ($i != $(i+c)) printf "%s|%s|%s|%s\n", $1, array[i], $i, $(i+c); }" 在我看来,由于混乱的转义,我不建议这样做。 - tshiono
另一个选项是利用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<=c; i++) if ($i != $(i+c)) printf "%s|%s|%s|%s\n", $1, array[i], $i, $(i+c); }' - tshiono
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接