awk, if else 当记录包含一个值时有条件
awk, if else conditional when record contains a value
我无法获取 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) }
([=10=] ~ /old/){ s=index([=10=],old); print substr([=10=],1,s-1) new substr([=10=],s+len) }{ print [=10=] }
' $val $key $file
输出:
"\("
NEW_NEW
./temp
###############
abcdefgh
abc"\("h
abcdefgh
abcde\(h
我想修复脚本,将 "\("
更改为 NEW_NEW
但跳过不带引号的括号...
"\("
NEW_NEW
./temp
###############
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h
编辑
这是我正在处理的真实脚本的缩写版本。答案需要包括上面示例中的变量扩展,以便我在更大的脚本中使用该命令。使用的 ARGV 格式保留了特殊字符,所以我的主要问题是为什么没有按预期触发条件。
此代码使用变量 val
、key
和 file
,但假设您可以更改 val
的内容以补偿 shell传递给 awk
时展开
$ file="./temp"; key="NEW_NEW"; val='"\\\("'; \
awk --posix -v val="$val" -v key="$key" '{gsub(val, key)}1' "$file"
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h
([=12=] ~ /old/)
表示 "do a regexp comparison between the current record ([=13=]
) and the literal regexp old
" 因此当 $0 包含 3 个字符 o
、l
、d
时匹配。您可能正在尝试对名为 old
的变量的内容进行正则表达式比较,该变量将是 [=19=] ~ old
(请参阅 How do I use shell variables in an awk script?) but you don't actually want that, you want a string comparison which would be index([=20=],old)
as shown in your previous question (),但由于某种原因您现在已将其移出条件condition { action }
awk 语句的一部分,并将其作为操作的第一部分。所以不要那样做。
您的脚本的另一个主要问题是您要从 shell 变量周围删除引号,因此它们会被 shell 解释并进行通配、文件名扩展等. 在 awk 甚至看到它们之前(参见 https://mywiki.wooledge.org/Quotes)。所以也不要那样做。
仅修复我提到的部分:
$ 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([=10=],old) { [=10=] = substr([=10=],1,s-1) new substr([=10=],s+len) }
{ print }
' "$val" "$key" "$file"
.
$ ./tst.sh
"\("
NEW_NEW
./temp
###############
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h
我无法获取 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) }
([=10=] ~ /old/){ s=index([=10=],old); print substr([=10=],1,s-1) new substr([=10=],s+len) }{ print [=10=] }
' $val $key $file
输出:
"\("
NEW_NEW
./temp
###############
abcdefgh
abc"\("h
abcdefgh
abcde\(h
我想修复脚本,将 "\("
更改为 NEW_NEW
但跳过不带引号的括号...
"\("
NEW_NEW
./temp
###############
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h
编辑
这是我正在处理的真实脚本的缩写版本。答案需要包括上面示例中的变量扩展,以便我在更大的脚本中使用该命令。使用的 ARGV 格式保留了特殊字符,所以我的主要问题是为什么没有按预期触发条件。
此代码使用变量 val
、key
和 file
,但假设您可以更改 val
的内容以补偿 shell传递给 awk
$ file="./temp"; key="NEW_NEW"; val='"\\\("'; \
awk --posix -v val="$val" -v key="$key" '{gsub(val, key)}1' "$file"
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h
([=12=] ~ /old/)
表示 "do a regexp comparison between the current record ([=13=]
) and the literal regexp old
" 因此当 $0 包含 3 个字符 o
、l
、d
时匹配。您可能正在尝试对名为 old
的变量的内容进行正则表达式比较,该变量将是 [=19=] ~ old
(请参阅 How do I use shell variables in an awk script?) but you don't actually want that, you want a string comparison which would be index([=20=],old)
as shown in your previous question (condition { action }
awk 语句的一部分,并将其作为操作的第一部分。所以不要那样做。
您的脚本的另一个主要问题是您要从 shell 变量周围删除引号,因此它们会被 shell 解释并进行通配、文件名扩展等. 在 awk 甚至看到它们之前(参见 https://mywiki.wooledge.org/Quotes)。所以也不要那样做。
仅修复我提到的部分:
$ 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([=10=],old) { [=10=] = substr([=10=],1,s-1) new substr([=10=],s+len) }
{ print }
' "$val" "$key" "$file"
.
$ ./tst.sh
"\("
NEW_NEW
./temp
###############
abcdefgh
abcNEW_NEWh
abcdefgh
abcde\(h