我使用以下脚本尝试使用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"
答案 0 :(得分:2)
有几件事:
$
不用于扩展变量(与shell不同)。只需使用变量名称。 $
使其引用某个字段 - 例如,foo = 1; print $foo
将打印第一个字段($1
)。//
标记内使用awk变量,但您可以使用~
匹配变量中包含的正则表达式,如$0 ~ some_variable
中所示。可以像往常一样指定范围。-v
选项也不例外。所以,把它们放在一起,你可以这样做:
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.