MacOS下Bash脚本中AWK插入文本无报错但失效问题
问题:MacOS下Bash脚本用AWK插入多行文本到YAML文件失败
问题场景
在MacOS的Bash脚本中,尝试用AWK工具向target.yaml插入指定多行文本,脚本运行无报错,但目标文件里完全没看到插入的内容。
target.yaml 原内容
# some comment alpha: charlie: - foo
使用的Bash脚本
#!/bin/bash # Define the lines to be added lines_to_add=" bravo: - bar" # Specify the .yaml file path yaml_file="../project/target.yaml" # Use awk to insert the lines at line three of the .yaml file awk -v lines="$lines_to_add" 'NR==3{print lines}1' "$yaml_file" > temp.yaml && mv temp.yaml "$yaml_file"
期望的target.yaml输出
# some comment alpha: bravo: - bar charlie: - foo
补充说明
直接在终端执行插入单个字符串的AWK命令是正常工作的:
awk -v lines="MY_NEW_LINE" 'NR==3{print lines}1' target.yaml > temp.yaml && mv temp.yaml target.yaml
解决方案
问题出在MacOS默认用的是BSD awk,它不支持通过-v选项传递包含换行符的变量——换行符会被自动转成空格,导致插入的内容变成一行乱码,看起来像是没插入。而你测试单行字符串没问题,是因为没有换行符的变量能正常传递。
方法1:不用-v,通过标准输入传递多行内容
修改脚本里的AWK调用部分,用printf把多行内容传入AWK的标准输入,然后在NR==3时读取并打印这些行:
#!/bin/bash lines_to_add=" bravo: - bar" yaml_file="../project/target.yaml" printf "%s" "$lines_to_add" | awk 'NR==3{while((getline line < "/dev/stdin")>0) print line}1' "$yaml_file" > temp.yaml && mv temp.yaml "$yaml_file"
方法2:改用GNU awk(gawk)
如果经常处理这类场景,建议安装GNU版本的awk(gawk),它支持多行变量传递:
- 先通过Homebrew安装:
brew install gawk
- 把脚本里的
awk换成gawk,原命令就能正常工作:
gawk -v lines="$lines_to_add" 'NR==3{print lines}1' "$yaml_file" > temp.yaml && mv temp.yaml "$yaml_file"
内容的提问来源于stack exchange,提问作者FunnyChef
相关产品推荐
相关产品推荐

