awk 不关心“特殊字符”。这在 sed 中:
sed '/<jobResulsDir/s/<jobResulsDir/<CommCellUser userName="'$4'" password="'$5'" > <\/CommCellUser> '$test' <jobResulsDir /'
这是在 awk 中的:
awk -v userName="$4" -v password="$5" -v test="$test" '
/<jobResulsDir/{ sub(/<jobResulsDir/, "<CommCellUser userName=" userName " password=" password " </CommCellUser> " test " <jobResulsDir ") }
{ print }
'
但您实际上不需要预先测试,/<jobResulsDir/
因为 sub() 仅在 RE 存在时才会发生,因此您可以将其缩写为:
awk -v userName="$4" -v password="$5" -v test="$test" '
{ sub(/<jobResulsDir/, "<CommCellUser userName=" userName " password=" password " </CommCellUser> " test " <jobResulsDir "); print }
'
不确定这是否是您的评论/问题所要求的,但如果您需要在值名称周围加上双引号,只需调整脚本以在您需要的地方提供它们:
awk -v userName="$4" -v password="$5" -v test="$test" '
{ sub(/<jobResulsDir/, "<CommCellUser userName=\"" userName "\" password=\"" password "\" </CommCellUser> \"" test "\" <jobResulsDir "); print }
'
最后,如果您愿意,可以通过以下一种方式拆分工作,使其更具可读性和效率:
awk -v userName="$4" -v password="$5" -v test="$test" '
BEGIN{
q = "\""
rep = \
"<CommCellUser userName=" q userName q\
" password=" q password q\
" </CommCellUser> " q test q\
" <jobResulsDir "
}
{ sub(/<jobResulsDir/, rep); print }
'
看着它以这种方式布置,我意识到我对 awk 不关心“特殊字符”有点撒谎。sub() 实际上确实关心 1 个“特殊字符”,即替换字符串中的“&”,因为它用于反向引用 sub() 中匹配的内容,因此您需要将“&”替换为“\&”在代表:
awk -v userName="$4" -v password="$5" -v test="$test" '
BEGIN{
q = "\""
rep = \
"<CommCellUser userName=" q userName q\
" password=" q password q\
" </CommCellUser> " q test q\
" <jobResulsDir "
}
{ gsub(/&/,"\\\\&",rep); sub(/<jobResulsDir/, rep); print }
它需要 4 个“\”,因为字符串文字在 awk 中被解释了两次(一次是在解释脚本时,一次是在执行脚本时),所以你需要 \\ 来代替 \ 来获得文字反斜杠。
如果您愿意,还有一种使用 match() 和 substr() 的替代方法,它没有该约束:
awk -v userName="$4" -v password="$5" -v test="$test" '
BEGIN{
q = "\""
rep = \
"<CommCellUser userName=" q userName q\
" password=" q password q\
" </CommCellUser> " q test q\
" <jobResulsDir "
}
match($0,/<jobResulsDir/) {
$0 = substr($0,1,RSTART) rep substr($0,RSTART+RLENGTH)
}
{ print }
'
就个人而言,我会使用 match()/substr() 方法,因为我讨厌转义字符。
只是循环回到我们开始的地方,如果你愿意,可以这样写:
awk -v userName="$4" -v password="$5" -v test="$test" '{
print (match($0,/<jobResulsDir/) ? substr($0,1,RSTART) "<CommCellUser userName=\"" userName "\"password=\"" password "\" </CommCellUser> \"" test "\" <jobResulsDir " substr($0,RSTART+RLENGTH) : $0)
}'