如何在if条件中匹配命令行参数并筛选YAML文件内容?
解决YAML文件按命令行参数匹配行并复制的问题
问题背景
需要实现逐行读取file.yml文件,检查每行是否包含指定的命令行参数(作为匹配关键词),将匹配成功的行写入file_copy.yml。现有代码及尝试写法存在匹配失效和语法错误问题:
现有简化代码:
while IFS= read -r line; do if [[ "$line" =~ ".*$1:" ]]; then echo "$line" >> file_copy.yml fi done < file.yml
曾尝试的无效写法:
"$line" == *".*\$1:"*
错误原因分析
- 正则匹配引号问题:
[[ ... =~ ... ]]中,正则表达式不需要加引号。加引号后,".*$1:"会被当作字面量字符串匹配,$1无法解析为命令行参数,同时正则元字符.和*失去正则语义。 - 通配符写法错误:通配符匹配使用
==时,不需要正则语法的.*,且\$1的转义会导致$1被当作字面量,无法解析为传入的参数。 - 参数传递潜在问题:若调用脚本时参数包含特殊字符(如空格、通配符)未加引号,会触发shell解析错误。
修复后的代码
#!/bin/bash # 检查是否传入命令行参数 if [ $# -eq 0 ]; then echo "请提供要匹配的关键词作为命令行参数" exit 1 fi # 可选:清空目标文件,避免多次执行重复追加内容 > file_copy.yml while IFS= read -r line; do # 正则匹配:直接使用未加引号的参数,自动解析为正则模式 if [[ "$line" =~ $1: ]]; then echo "$line" >> file_copy.yml fi done < file.yml
补充说明
- 通配符匹配替代方案:若偏好使用通配符而非正则,可将判断条件改为:
这里的if [[ "$line" == *"$1:"* ]]; then*是shell通配符,匹配任意长度字符,"$1:"加引号可避免参数含特殊字符时的解析错误。 - 参数传递规范:调用脚本时,若参数包含空格或特殊字符,必须用引号包裹,例如:
./your_script.sh "user name" - 匹配精度调整:若不需要严格匹配YAML键的
:后缀,可将条件中的:去掉,改为$1即可。
内容的提问来源于stack exchange,提问作者Husain Shaikh
相关产品推荐
相关产品推荐

