awk,如果记录包含值,则为条件

问题描述 投票:0回答:2

当记录包含值时,我很难获得awk if / else条件来正确触发。在Mac OS Catalina上的zsh中运行此程序。

此脚本(问题在倒数第二行)...

echo "abcdefgh" >  ./temp
echo "abc\"\(\"h" >> ./temp
echo "abcdefgh" >> ./temp
echo "abcde\(h" >> ./temp 

val='"\("'
key="NEW_NEW"
file="./temp"

echo $val
echo $key
echo $file

echo ""
echo "###############"
echo ""

awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
    ($0 ~ /old/){ s=index($0,old); print substr($0,1,s-1) new substr($0,s+len) }{ print $0 }
' $val $key $file

输出:

"\("
NEW_NEW
./temp

###############

abcdefgh
abc"\("h
abcdefgh
abcde\(h

我想修复脚本,以便将"\("更改为NEW_NEW,但是跳过不带引号的括号...

"\("
NEW_NEW
./temp

###############

abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h

编辑

这是我正在使用的真实脚本的缩写版本。答案将需要包括以上示例所具有的变量扩展,以便我在较大的脚本中使用该命令。使用的ARGV格式保留了特殊字符,因此我的主要问题是为什么没有按预期触发条件。

macos if-statement awk zsh contains
2个回答
1
投票

($0 ~ /old/)的意思是“在当前记录($0)和文字正则表达式old之间进行正则表达式比较”,因此当$ 0包含3个字符old时,它匹配订购。您可能正在尝试对名为old的变量的内容进行正则表达式比较,该变量的内容为$0 ~ old(请参见How do I use shell variables in an awk script?),但是您实际上并不希望那样做,而是想要一个字符串比较项,其内容为[C0 ],如上一个问题(index($0,old))所示,但由于某种原因现在已将其移出https://stackoverflow.com/a/62096075/1745001 awk语句的条件部分,并将其作为操作的第一部分。所以不要那样做。

脚本的另一个主要问题是,您正在从shell变量周围删除引号,因此它们会被shell解释,并在awk甚至没有看到它们之前就进行了遍历,扩展文件名等操作(请参阅[ C0])。所以也不要这样做。

仅修复了我提到的部分:

condition { action }

https://mywiki.wooledge.org/Quotes

1
投票

此代码使用变量$ cat tst.sh echo "abcdefgh" > ./temp echo "abc\"\(\"h" >> ./temp echo "abcdefgh" >> ./temp echo "abcde\(h" >> ./temp val='"\("' key="NEW_NEW" file="./temp" echo "$val" echo "$key" echo "$file" echo "" echo "###############" echo "" awk ' BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) } s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) } { print } ' "$val" "$key" "$file" $ ./tst.sh "\(" NEW_NEW ./temp ############### abcdefgh abcNEW_NEWh abcdefgh abcde\(h val,但假定您可以更改key的内容以补偿传递给file时的外壳扩展

val
© www.soinside.com 2019 - 2024. All rights reserved.