【问题标题】:Use array variable in awk?在awk中使用数组变量?
【发布时间】:2016-11-30 05:49:30
【问题描述】:
A=(aaa bbb ccc)    
cat abc.txt | awk '{ print $1, ${A[$1]} }'

我想根据 $1 索引一个数组元素,但上面的代码在 awk 语法中不正确。有人可以帮忙吗?

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    您不能使用在awk 中生成的值来索引bash 数组,即使您没有使用单引号(从而防止bash 进行任何替换)。不过,您可以将数组传入。

    A=(aaa bbb ccc)
    awk -v a="${A[*]}" 'BEGIN {split(a, A, / /)}
                         {print $1, A[$1] }' <abc.txt
    

    由于 awk 内部的 split 功能,A 的元素不能包含空格或换行符。如果您需要做一些更有趣的事情,请将数组设置在 awk 内。

    awk 'BEGIN {a[1] = "foo bar"  # sadly, there is no way to set an array all
                a[2] = "baz"    } #   at once without abusing split() as above
               {print $1, a[$1] }' <abc.txt
    

    (澄清:bash 替换变量 之前 调用您要替换的参数的程序,所以当您在 awk 中找到 $1 时,问 @987654331 为时已晚@ 使用它来替换 A 的特定元素。)

    【讨论】:

    • 这是一个错字。谢谢你告诉我,我已经修好了。
    • @kurumi:嗯?这正在取代“cat 的无用使用”。
    • @geekosaur, awk 接受一个输入文件。 awk '{}' filename
    • AWK 将接受文件名作为参数,而无需使用 &lt; 重定向它,正如 kurumi 指出的那样。而awk '{...}' A=foo filename will work, the form that you have, awk A=foo '{...}' filename` 不会。但是,您可以使用awk -v "A=foo" '{...}' filename
    • 这不仅仅是个人喜好,两种方法之间存在技术差异。例如,如果您使用输入重定向,则 awk 无法填充 FILENAME 变量,因此在您的 awk 脚本中您无权访问输入文件的名称。当无法打开文件和其他事情(性能不是差异化因素)时,使用重定向的好处就出现了,但鉴于丢失 FILENAME,它们不值得恕我直言。 comp.unix.shell NG 的一些人可能会提供详细信息,但可能会提出其他异议。
    【解决方案2】:

    如果您要对 A 数组进行硬编码,您可以在 awk 中初始化它

    awk 'BEGIN{A[0]="aaa";A[1]="bbb"}{ print $1, A[$1] }' abc.txt
    

    【讨论】:

      【解决方案3】:

      单引号内的 awk 程序看不到 shell 环境变量 A。通常,如果使用双引号而不是单引号,则可以进行一些 shell 替换,但这是由 shell 在 awk 之前完成的调用。总的来说,尝试以这种方式将 shell 和 awk 结合起来是很费劲的。如果可能的话,我会采用 kurumi 使用 awk 数组的方法。

      单引号:不可穿透的面纱。 双引号:一般来说太辛苦了。 所以选择你的毒药:shell 或 awk。 否则:您的代码可能会失败。

      【讨论】:

        【解决方案4】:

        您还可以使用 printf 在单独的行上打印数组的每个元素并将其通过管道传输到 awk。此代码将简单地从 awk 打印 bash 数组 (bash_arr):

        bash_arr=( 1 2 3 4 5 )
        printf '%s\n' "${bash_arr[@]}" | 
            awk '    { awk_arr[NR] = $0 }
                 END {
                     for (key in awk_arr) {
                         print awk_arr[key]
                     }
                 }'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-17
          • 1970-01-01
          • 2014-01-20
          • 2022-10-14
          • 2012-04-19
          • 2021-08-13
          • 2023-03-30
          • 2013-11-19
          相关资源
          最近更新 更多