如何用Bash循环结合Awk的FPAT提取引号内逗号分隔值
解决PING.cfg文件引号内逗号分隔值的拆分问题
问题原因
你原代码的核心问题是同时使用了FPAT和-F',',这两个参数互斥:FS(通过-F指定的分隔符)会覆盖FPAT的匹配规则,导致awk直接按逗号拆分整行,把NODE01="router当作第一个字段、10.0.0.1当作第二个字段,完全偏离了提取引号内内容的预期。另外,for n in $(grep...)的循环方式存在潜在风险——如果后续行出现空格,会被错误拆分,更可靠的是用while read循环。
解决方案
方案1:用Bash内置命令处理(无需awk,高效简洁)
while IFS= read -r line; do # 提取引号包裹的内容 quoted_content="${line#*\"}" quoted_content="${quoted_content%\"*}" # 按逗号拆分内容到变量 IFS=',' read -r nodename hostip ping_count <<< "$quoted_content" echo "NODE is $nodename and HOSTIP is $hostip" done < <(grep NODE PING.cfg)
${line#*\"}:去掉行首到第一个双引号的所有内容${quoted_content%\"*}:去掉最后一个双引号到行尾的所有内容IFS=',' read ...:用逗号作为分隔符,将引号内的内容拆分到三个变量中
方案2:用Awk一次性处理整行
grep NODE PING.cfg | awk -F'"' '{ split($2, fields, ",") printf "NODE is %s and HOSTIP is %s\n", fields[1], fields[2] }'
-F'"':将行按双引号拆分成三部分,$2即为引号内的完整内容split($2, fields, ","):把引号内的内容按逗号拆分到数组fields,直接取对应元素输出
方案3:修正原有Awk+循环写法
如果坚持使用原循环结构,需去掉-F',',改用FPAT提取引号内容后再拆分:
for n in $(grep NODE PING.cfg); do read -r nodename hostip <<< $(echo "$n" | awk -v FPAT='"[^"]+"' '{ gsub(/"/, "", $2) split($2, arr, ",") print arr[1] " " arr[2] }') echo "NODE is $nodename and HOSTIP is $hostip" done
FPAT='"[^"]+"':匹配所有双引号包裹的内容,$2就是引号内的字符串gsub(/"/, "", $2):去掉双引号split拆分后输出两个字段,再用bash的read赋值到变量
内容的提问来源于stack exchange,提问作者SmplJohn
相关产品推荐
相关产品推荐

