【问题标题】:not getting array value in awk没有在 awk 中获取数组值
【发布时间】:2017-08-29 02:11:07
【问题描述】:

我想将包含 testfile.ps 的所有其他内容的数组值插入到 result.ps 文件中,但数组值没有打印出来,请帮忙。 我的要求是每次满足条件时数组下一个索引值应该与 testfile.ps 的其他内容一起打印到 result.ps 中

实际上 arr[0] 和 arr[1] 在我的项目中是大字符串,但为简单起见,我正在编辑它

#!/bin/bash
a[0]=""lineto""\n""stroke""
a[1]=""476.00"" ""26.00""

awk '{ if($1 == "(Page" ){for (i=0; i<2; i++){print $arr[i]; print $0; }} 
else print }' testfile.ps > result.ps

测试文件.ps

(Page 1 of 2 )
move
(Page 1 of 3 )
"gsave""\n""2.00"" ""setlinewidth""\n"

result.ps 应该是

(Page 1 of 2 )
lineto
stroke
move
(Page 1 of 3 )
476.00 26.00
gsave
2.00
setlinewidth

表示一旦满足第二次条件,数组索引应该递增到 1,它应该打印 a[1]

我也应用了这个方法,只有单个数组元素但没有得到任何输出

awk -v "a0=$a[0]" 'BEGIN {a[0]=""lineto""stroke""; if($1 == "move" ){for (i in a){ print a0;print $0; }} else print }' testfile.txt

编辑: 嗨,我已经在一定程度上解决了这个问题,但卡在一个地方,我如何比较两个字符串,如 "a=476.00 1.00 lineto\nstroke\ngrestore\n" 和 "b=26.00 moveto\n368.00 1.00 lineto\ n" 在 awk 命令中,我正在尝试

awk -v "a=476.00 1.00 lineto\nstroke\ngrestore\n" -v "b=26.00 moveto\n368.00 1.00 lineto\n"  -v "i=$a" '{
if ($1 == "(Page" && ($2%2==0 || $2==1) && $3 == "of"){  
    print i; 
    if [ i == a ];then
        i=b; print $0;  
    fi 
else if [ i == b ];then 
        i=c; print $0;  
    fi
else print $0; 
}'testfile.txt

【问题讨论】:

  • awk 不是 shell,它是一个完全不同的工具,有自己的语法、变量等。你不能在 awk 中使用 shell 变量,就像在 C 或 Java 中使用 shell 变量一样。 edit您的问题包括简洁、可测试的样本输入和预期输出,以便我们为您提供帮助。
  • 即使 shell 和 awk 使用相同的变量,它们也必须拼写相同,即 a[0] !- $arr[0] ;-) 。祝你好运。
  • 您对$arr[i] 有什么期望?您是否尝试引用上面定义的 shell 数组 a?它甚至不是同名,而且你不能(轻松)在 awk 中获取 shell 变量...
  • @EdMorton:感谢您的评论,为了更清楚,我已经编辑了问题
  • @dawg:感谢您的评论,为了更清楚,我已经编辑了这个问题

标签: bash shell awk sed string-comparison


【解决方案1】:

您在 awk 程序中使用了一个从未初始化的变量 arr

在您的情况下,您希望将一个变量从 shell 传递给 awk。从 awk 手册页:

   -v var=val
   --assign var=val
          Assign the value val to the variable var, before execution of the program  begins.   Such
          variable values are available to the BEGIN rule of an AWK program.

因此,您需要类似的东西

awk -v "a0=$a[0]" -v "a1=$a[1]" .....

在 BEGIN 块中,您可以根据需要以任何方式从变量 a0 和 a1 设置数组 arr

【讨论】:

  • :嗨,到目前为止我只尝试了 a0,但它没有给我任何输出,请帮助 awk -v "a0=$a[0]" 'BEGIN {a[0] =""lineto""中风""; if($1 == "move" ){for (i in a){ print a0;print $0; }} 否则打印 }' testfile.txt
  • 嗨 user1934428,你能纠正它吗,我没有得到想要的输出 awk -v s="gsave\ninitmatrix\n 2.00 setlinewidth \n 368.00 26.00 moveto \n 368.00 1.00 lineto" ' BEGIN { n =split(s,a,"\n") } 1 /((页面 && $2~/^[0-9][0-9]*/ && $2%2==0 && $3== "of") / && i
  • 请以正确格式发布代码。您可以通过编辑您的原始帖子来做到这一点。
  • 嗨,我的问题在一定程度上得到了解决,但我一直在比较 awk 命令中的两个长字母数字字符串,请查看上面已编辑的问题部分
  • 比较两个字符串是使用 == 运算符完成的,但我注意到几个奇怪的地方:(1)您通过 shell 变量 $a 初始化 awk 变量 i,因为这是一个bash数组,相当于数组的第一个元素。 (2) 在 awk 程序中 if 之后使用有趣的方括号。查找 awk 手册页:您需要圆括号。 (3) testfile.txt前面没有空格
【解决方案2】:

使用分隔符将数据收集到单个 var:

$ awk -v s="lineto\nstroke;476.00 26.00" '  # ; as separator
BEGIN{ n=split(s,a,";") }                   # split s var to a array
1                                           # output record
/\(Page/ && i<n { print a[++i] }            # if (Page and still data in a
' file
(Page 1 of 2 )
lineto
stroke
move
(Page 1 of 3 )
476.00 26.00
"gsave""\n""2.00"" ""setlinewidth""\n"

【讨论】:

  • 我不明白你的意思。请编辑您的问题以反映真实情况。
  • 嗨詹姆斯,你能纠正它吗,我没有得到想要的输出 awk -v s="gsave\ninitmatrix\n 2.00 setlinewidth \n 368.00 26.00 moveto \n 368.00 1.00 lineto" ' BEGIN { n =split(s,a,"\n") } 1 /((页面 && $2~/^[0-9][0-9]*/ && $2%2==0 && $3== "of") / && i
  • 好吧,难怪条件部分是 fubar 并且您的数据与这些条件不匹配,因为 $2 始终为 1。这更像是:awk -v s="gsave\ninitmatrix\n 2.00 setlinewidth \n 368.00 26.00 moveto \n 368.00 1.00 lineto" ' BEGIN { n=split(s,a,"\n") } 1; $1=="(Page" &amp;&amp; $2~/^[0-9][0-9]*/ &amp;&amp; $2%2==0 &amp;&amp; $3== "of" &amp;&amp; i&lt;n { print s } ' file
  • 嗨詹姆斯,我在主要问题中添加了真实情况,请尝试获取它并帮助我......你的答案应该有什么变化
  • 嗨,我的问题在一定程度上得到了解决,但我一直在比较 awk 命令中的两个长字母数字字符串,请查看上面已编辑的问题部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 2016-08-22
  • 2020-01-25
  • 2012-03-10
  • 1970-01-01
  • 2018-10-11
相关资源
最近更新 更多