【问题标题】:AWK script stops working after shell variables are added添加 shell 变量后 AWK 脚本停止工作
【发布时间】:2023-10-29 00:31:01
【问题描述】:

我有下面的代码(感谢这个社区的成员),它的行为很奇怪。当我对动态部分进行硬编码时,它可以工作......当我使用参数运行代码时,它什么也不做。这是代码(有和没有变量)以及输出(屏幕截图)

echo "Attempt A:"
echo "--------------------"
echo "awk -v n=4 '{a[p]=$0; p=(p+1)%n}
              /(Something)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
              f{print}
              /\/Interface/{f=0}' file.log | awk 'BEGIN{ORS=RS=\"</Interface>\n -------------------\"}
      /name=\"Andy\"/' > AttemptA.txt"

awk -v n=4 '{a[p]=$0; p=(p+1)%n}
              /(Something)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
              f{print}
              /\/Interface/{f=0}' file.log | awk 'BEGIN{ORS=RS="</Interface>\n -------------------"}
      /Name="Andy"/' > AttemptA.txt

aaid="Andy"
aalog=file.log

echo "-------------------------------------------------------------------------------------------------"
echo "-------------------------------------------------------------------------------------------------"
echo ""
echo ""
echo "Attempt B:"
echo "awk -v n=4 '{a[p]=$0; p=(p+1)%n}
              /(Something)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
              f{print}
              /\/Interface/{f=0}' ${aalog} | awk 'BEGIN{ORS=RS=\"</Interface>\n -------------------\"}
      /Name=\"${aaid}\"/' > AttemptB.txt"

awk -v n=4 '{a[p]=$0; p=(p+1)%n}
              /(Something)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
              f{print}
              /\/Interface/{f=0}' ${aalog} | awk 'BEGIN{ORS=RS="</Interface>\n -------------------"}
      /Name="${aaid}"/' > AttemptB.txt

这是结果(截图):

运行代码:http://imgur.com/FEJW5uR

创建的文件:http://imgur.com/NytUL02

知道为什么它会识别所有内容,打印相同的命令,但一个实际有效,另一个无效吗?

【问题讨论】:

  • W.r.t.使用 "${aaid}" 而不是 "Andy" --- 看起来您正试图从 awk 脚本中引用 shell 变量。 awk 无权访问它。
  • 您可以通过在 awk 脚本中的单引号和 dbl 引号之间切换来在 awk 脚本中嵌入 shell 变量,以“公开” awk 脚本中的 shell var 值,即 awk '/Name=' "${aaid}" '/ ......' I在单引号和 dbl-quote 之间添加了一个空格,以使这些字符分别突出。祝你好运。
  • ....我们中的其他人可以将其标记为不正确:-)。不要像@shelter 建议的那样跳入/跳出外壳,请使用-v aaid="$aaid" ... $0~("Name=\""aaid"\"")。请参阅 cfajohnson.com/shell/cus-faq-2.html#Q24 并记住 - awk 不是外壳。
  • 大声笑,我同意 Ed 的观点;-/,-v var="$val" 是更好的解决方案,但我希望您意识到 shell 单引号会阻止 shell 变量可见。对于一次性的,有时它是比使用-v var="$val" 更快的解决方案,祝大家好运。
  • 我发现 shell 引用很难记住如何正确使用它需要更长的时间才能弄清楚(x=3.0; awk 'BEGIN{print "'"$x"'"}'),而不是仅仅以稳健的方式(x=3.0; awk -v x="$x" 'BEGIN{print x}')所以我无法想象将 shell 变量值扩展为 awk 脚本代码的实际部分(就像第一个版本一样)的场景有什么意义。

标签: awk ksh


【解决方案1】:
awk -v aaid="$aaid" 'BEGIN{ORS=RS="</Interface>\n -------------------"}
    $0 ~ "Name=\""aaid"\""' > AttemptB.txt

【讨论】:

  • 好的,你是说在 -v 中我可以在 awk 和 shell 之间建立一座桥梁?我可以这样定义多少个变量?如何定义多个变量?
  • 没错。 -v 是将值从 shell 传递到 awk 的方法。与您使用 -v n=4 所拥有的类似,您可以轻松地使用 shell 变量,而不是硬编码的 4。您可以多次包含该选项,例如-v color=red -v size=XL -v quantity=7.
  • 明白了。谢谢先生。