我想使用
awk
替换文件的文本。示例脚本:
#!/bin/bash
test_file="test.md"
key="KEY"
value="- & -"
echo "AAA $key AAA" > "$test_file"
echo "Original: $(cat "$test_file")"
tmp=$(mktemp)
awk -v s="$key" -v r="$value" '{sub(s,r)}1' "$test_file" > "$tmp" && mv "$tmp" "$test_file"
echo "Updated: $(cat "$test_file")"
rm "$test_file"
预期输出是:
原版:AAA KEY AAA
更新:AAA - & - AAA
但是,它输出不正确(“KEY”保留在那里,而不是“&”符号):
原版:AAA KEY AAA
更新:AAA - KEY - AAA
我也尝试过下面的方法,但没有成功。
awk '
BEGIN { s=ARGV[1]; r=ARGV[2]; delete ARGV[1]; delete ARGV[2]; }
{ sub(s,r) }1
END {}' "$key" "$value" "$test_file" > "$tmp" && mv "$tmp" "$test_file"
用其他符号替换“&”就可以了。对于处理此案有什么建议吗?
请忽略这个问题中的
sed
命令,因为我还有其他一些情况需要处理,而awk
适合我的情况,除了这个奇怪的“&”问题。
您可以像这样使用
awk
并替换 bash:
key="KEY"
value="- & -"
awk -v s="$key" -v r="${value//&/\\\\&}" '{sub(s,r)}1' <<< 'AAA KEY AAA'
AAA - & - AAA
这里
"${value//&/\\\\&}"
将用 &
替换 \\&
。
我将利用 GNU
AWK
来完成此任务,如下所示
key="KEY"
value="- & -"
echo "AAA $key AAA" | awk --assign FS="$key" --assign OFS="$value" '{$1=$1;print}'
提供输出
AAA - & - AAA
说明:我通知 GNU
AWK
字段分隔符是键,输出字段分隔符是值,然后对于每一行,我触发重建 ($1=$1
) 和 print
结果。请记住,您仍然需要警惕按键内具有特殊含义的字符。如果您想了解更多有关 FS
或 OFS
的信息,请阅读 8 强大的 Awk 内置变量 – FS、OFS、RS、ORS、NR、NF、FILENAME、FNR
(在 GNU Awk 5.1.0 中测试)