如何让awk单独解析bash多行变量中的每一行?
问题描述
在bash脚本parse.sh中定义了多行变量LOG_BUF,尝试通过awk解析该变量并打印所有包含pat的行,脚本代码如下:
#!/bin/bash LOG_BUF=$(cat <<-END pat TEST_a pat TEST_b TEST_c pat TEST_d END ) echo ${LOG_BUF} | awk 'BEGIN{}; /pat/{printf("%d %s", NR, $0); printf("\n")}; END{printf("\n")}'
预期输出:
$ ./parse.sh 1 pat TEST_a 2 pat TEST_b 4 pat TEST_d
实际输出:
$ ./parse.sh 1 pat TEST_a pat TEST_b TEST_c pat TEST_d
问题核心:awk将整个字符串视为单条记录,未按多行解析,需调整写法让awk识别换行并逐行处理。
解决方案
1. 用双引号包裹变量后通过echo输出
直接使用echo ${LOG_BUF}时,bash会自动将变量内的换行符替换为空格,导致所有内容合并成一行传入awk。给变量加上双引号即可保留原始换行格式:
echo "${LOG_BUF}" | awk '/pat/{printf("%d %s\n", NR, $0)}'
2. 用printf输出变量(更稳定)
部分环境下echo的行为可能存在差异,使用printf能更可靠地保留变量内的换行符:
printf "%s" "${LOG_BUF}" | awk '/pat/{printf("%d %s\n", NR, $0)}'
3. 使用Here String直接传入awk
借助bash的Here String特性,无需管道即可将变量内容直接作为awk的标准输入,避免额外的字符处理:
awk '/pat/{printf("%d %s\n", NR, $0)}' <<< "${LOG_BUF}"
补充说明
预期输出中的mem应为笔误,原脚本匹配的是pat,上述修正后的代码输出会与修正后的预期一致。
内容的提问来源于stack exchange,提问作者ysap
相关产品推荐
相关产品推荐

