无法将命令行参数传递给嵌入在bash脚本中的awk脚本

时间:2015-01-20 15:16:39

标签: regex bash awk

我使用以下脚本尝试使用awk搜索和替换多行模式。 awk脚本在直接使用时工作正常但在通过传递命令行参数通过bash脚本尝试实现该功能时,参数不会按预期放入awk并产生不良结果。我用来测试awk脚本和预期结果的示例文件如下:

档案:

<A>
<B>
Port id=X
<C>
Port id=hey
Port no=hi
</C>
</B>
Port id=Z
</A>

现在,如果我想用网络替换'端口',但只在范围之下......,我只需按下面的方式运行awk,这样就可以了:

awk '/<A>/,/<C>/ {gsub(/Port/,"Network"); } {print;}' filename

输出:

<A>
<B>
Network id=X
<C>
Port id=hey
Port no=hi
</C>
</B>
Port id=Z
</A>

我试图通过编写如下脚本来使功能具有通用性,该脚本将文件名,范围,模式替换,并将模式作为命令行参数放置到位并在awk脚本中使用它们,但它不会工作。

有没有人可以帮助我们如何将命令行参数传递给awk脚本来实现我可以通过直接执行awk脚本来实现的功能?

#!/bin/bash

echo "Enter file-name ,scope to be matched separated with space , pattern to be replaced , pattern to be placed"
echo "The file name is :$1 ,the scope to be matched : $2 - $3 , the pattern to be replaced is :$4 , pattern to be placed is: $5"
echo "Scope Start : $2"
echo "Scope End : $3"

awk -v F=$1 -v SS=$2 -v SE=$3 -v RE=$5 -v TRE=$4 '/"$SS"/,/"$SE"/ {gsub(/'"$TRE"'/,RE); } {print;}' "$1"

1 个答案:

答案 0 :(得分:2)

有几件事:

  1. 在awk脚本中,$不用于扩展变量(与shell不同)。只需使用变量名称。 $使其引用某个字段 - 例如,foo = 1; print $foo将打印第一个字段($1)。
  2. 虽然您无法在//标记内使用awk变量,但您可以使用~匹配变量中包含的正则表达式,如$0 ~ some_variable中所示。可以像往常一样指定范围。
  3. 应该几乎总是引用Shell变量,并将它们传递给awk的-v选项也不例外。
  4. 所以,把它们放在一起,你可以这样做:

    awk -v SS="$2" -v SE="$3" -v TRE="$4" -v RE="$5" '$0 ~ SS,$0 ~ SE { gsub(TRE, RE) } { print }' "$1"
    

    awk代码在哪里

    $0 ~ SS, $0 ~ SE {  # between lines that match SS and SE,
      gsub(TRE, RE)     # replace stuff that matches TRE with RE
    }
    { print }           # and print everything.