由于替换字段中的变量,导致awk -v紧急退出/无法打开文件

时间:2019-02-04 16:48:31

标签: bash shell awk

我正在尝试使用awk输入一个字符串,其中包含变量在模式的第n个匹配项之上(目前)。我的实际目标是通过在return (0);的第二个匹配项的正上方添加包含例如printf("%s%d%s", str00,int01,str03);的行来修改real_printf.c文件的内容。我正在创建一个随机的printf生成器,作为学校项目的自我加成((在.c中重新编码printf)),并且已经可以输入随机变量声明,%和转换指示器之间的转换标志等。 。这是我拥有一个可行的原型之前的最后一步。

我已经有了用于return (0);匹配项的awk命令,但是我遇到了第一个错误,即我被0除并因此结束了awk执行。参见下面的代码:

1)awk '/return/{c++;if(c==2){ print "\t\tprintf("'$input_pf'", '$var_name');"; c=1 }} 1' .annex/real_printf.c

在阅读了许多在线资源之后,我通过使用awk -v并声明了变量,将上面的代码更改为下面的代码,以纠正此错误:

2)awk -v input="$input_pf" name="$var_name" "/return/{c++;if(c==2){ print "\\t\\tprintf\(\"$input\", $name\);"; c=1 }} 1" .annex/real_printf.c

对于上面的代码,shell返回了以下错误:

awk -v input=%p name=ptr00 '/return/{c++;if(c==2){ print \t\tprintf("",' ')'
awk: can't open file /return/{c++;if(c==2){ print \t\tprintf("",
 source line number 1
+ '; c=1 }} 1' .annex/real_printf.c
.annex/modify/pct_conv.sh: line 34: ; c=1 }} 1: command not found

因此,我决定删除awk -v之后变量周围的双引号,请参见下面的代码。

3)awk -v input=$input_pf name=$var_name "/return/{c++;if(c==2){ print "\\t\\tprintf\(\"$input\", $name\);"; c=1 }} 1" .annex/real_printf.c

我现在得到以下结果,并且缺乏尝试的想法:

awk -v input=%f%o%s name=f00,o01,str02 '/return/{c++;if(c==2){ print \t\tprintf("",' ')'`
`awk: syntax error at source line 1
 context is
     ``>>> name=f00,o01, <<<``
awk: bailing out at source line 1
+ '; c=1 }} 1' .annex/real_printf.c
.annex/modify/pct_conv.sh: line 34: ; c=1 }} 1: command not found

应该是语法问题,否则我可能会在一行中从awk请求太多。也许awk甚至不是解决此问题的最佳工具。我尝试使用sed -i '' 's/return (0);/printf("$input_pf", $var_name)/2'来达到我的模式的第二个匹配,但是它也不起作用。

您将如何处理此问题?

1 个答案:

答案 0 :(得分:3)

# assign some values so we can test
input_pf=%f%o%s
var_name=f00,o01,str02

# sample input to exercise the code
input=$(cat <<'EOF'
return
return
return
return
EOF
)

# actual code here
awk -v input="$input_pf" -v name="$var_name" '
/return/ {
  if(count++ > 0) {
    printf "\t\tprintf(\"%s\", %s);\n", input, name
  }
}
1 { print }' <<<"$input"

注意:

  • 我们在每个-v对之前放置一个单独的name=value。如果没有此设置,第二对name=value将被视为您的awk脚本,其后的参数将被视为输入文件名。
  • 我们总是 用双引号引用shell扩展。
  • 我们将awk代码放在引号中,因此它不会被shell破坏。
  • 在引用awk变量时,我们使用$(因为这仅是shell语法)。

有了这些更改,以上内容正确(据我所知,在问题中未提供示例输入或输出)返回:

return
        printf("%f%o%s", f00,o01,str02);
return
        printf("%f%o%s", f00,o01,str02);
return
        printf("%f%o%s", f00,o01,str02);
return