sed如何用正则捕获的文件名对应文件内容替换匹配行
sed匹配行时读取捕获组对应文件替换整行的实现方法
你写的参考命令无法生效,核心原因是sed的r命令参数在脚本加载时就会被固定解析,不会在运行时替换正则捕获组的内容,写r"\1"会让sed直接尝试读取名为\1的文件,完全达不到预期效果。
GNU sed 最简实现(绝大多数Linux环境默认兼容)
直接使用替换命令的e执行标识即可,命令如下:
sed -E '/^file:\s*(\S+)/s//cat \1/e' file.txt
命令逻辑说明:
- 第一部分正则
/^file:\s*(\S+)/用来定位目标行:匹配所有行首为file:、后接任意空白、再跟非空白文件名字符串的行 - 后续的
s//cat \1/e是核心替换逻辑:空匹配规则//会自动复用前面的定位正则,把匹配到的整行替换为cat 提取到的文件名格式的shell命令;末尾的e标识是GNU sed专属功能,会直接执行模式空间内的shell命令,再用命令的输出结果(也就是对应文件的内容)替换掉原来的整行 - 所有不匹配规则的行会原样输出,不会被改动
非GNU sed环境(如macOS自带BSD sed)兼容方案
BSD sed没有替换命令的e标识,可以借助shell循环实现同等效果:
while IFS= read -r line; do if [[ "$line" =~ ^file:\s*(\S+) ]]; then cat "${BASH_REMATCH[1]}" else echo "$line" fi done < file.txt
注意事项
- 以上两种方案都会直接把匹配到的
file:xxx整行替换为对应文件的内容,不会保留原行 - 确保捕获到的文件路径正确、有可读权限,否则执行时会抛出cat命令的报错
- 如果需要匹配带空格的文件名,可以把定位正则修改为
/^file:\s*(.+)/,捕获file:后的所有内容作为文件名即可
内容的提问来源于stack exchange,提问作者user17227456
相关产品推荐
相关产品推荐

