如何在Bash中用grep读取文本文件中的多行属性
解决GitBash中grep读取多行构建属性的问题
场景说明
构建文件中包含单行/多行属性,其中REFLIBS这类属性通过反斜杠\换行延续值,同时存在bash风格注释行(以#开头)需要忽略,示例内容:
REFLIBS=module.o testModule1.o libutil.a \ libdebug.a \ libxfor.a SOURCEFILES=client.c FLAGS= HEADERS=linkedlist.h #OLD_REFLIBS ignore lines with bash-style comments #HEADERS=utils.h
原问题
使用grep -i -m 1 -E '^REFLIBS=' test.txt仅能捕获第一行反斜杠前的内容,无法获取完整的多行属性值,期望输出合并后的单行值:
module.o testModule1.o libutil.a libdebug.a libxfor.a
解决方案
方法1:临时修改IFS结合grep处理
修改输入字段分隔符(IFS)为反斜杠,让bash将所有以反斜杠结尾的关联行视为连续内容,再通过文本处理清理格式:
# 临时修改IFS仅作用于当前命令替换,不影响全局 REFLIBS_CAPTURE=$(IFS='\' ; grep -A99 -i -E '^REFLIBS=' test.txt | tr -d '\n' | sed 's/REFLIBS=//; s/[[:space:]]\+/ /g; s/^ //; s/ $//') echo "$REFLIBS_CAPTURE"
grep -A99:捕获匹配行及后续99行(足够覆盖多行属性的延续行)tr -d '\n':删除所有换行符sed:移除REFLIBS=前缀,将多个连续空格替换为单个空格,清理首尾空格
方法2:用sed直接完成匹配+合并+格式化
sed可以一次性完成多行匹配、合并和格式清理,无需依赖grep:
REFLIBS_CAPTURE=$(sed -n '/^REFLIBS=/{:a; s/\\$//; N; /\\$/ba; s/REFLIBS=//; s/[[:space:]]\+/ /g; s/^ //; s/ $//; p}' test.txt) echo "$REFLIBS_CAPTURE"
sed逻辑说明:
/^REFLIBS=/:定位到目标属性行:a:定义循环标签s/\\$//:删除行尾的反斜杠N:读取下一行追加到当前行/\\$/ba:如果新行尾仍有反斜杠,回到循环标签a继续处理- 最后通过sed替换清理格式并输出结果
关于IFS修改的说明
你提到的修改IFS方案是可行的,核心思路是通过调整bash的输入分隔规则,将反斜杠作为行连接的标记,把多行内容识别为连续的字符串,再配合文本处理工具完成格式整理。需要注意仅在局部(如命令替换内)临时修改IFS,避免改变shell的默认行为。
内容的提问来源于stack exchange,提问作者raffian
相关产品推荐
相关产品推荐

