如何在BASH中将匹配行替换为指定文件的全部内容?
解决方案
给你两种兼容不同场景的实现方式,都可以完美处理数百行的大文件插入,不会受特殊字符影响:
方案1:通用awk实现(全平台兼容,更安全)
这个方案支持Linux、macOS等所有带awk的环境,不会执行shell命令,避免注入风险,是最稳妥的选择:
awk ' # 匹配格式为「INPUT 文件名」的行 /^INPUT [^ ]+$/ { # 拼接得到实际要读取的文件名 filename = $2 ".txt" # 逐行读取目标文件内容输出 while ((getline line < filename) > 0) { print line } close(filename) # 跳过原INPUT行的输出 next } # 输出其他未匹配的原有行 1' 你要处理的目标文件
如果需要直接修改原文件,在命令后加输出重定向即可:
awk '上述逻辑' 原文件 > tmp && mv tmp 原文件
方案2:GNU sed极简实现(仅Linux环境适用)
如果你用的是Linux系统(默认带GNU sed),可以用sed的e标记直接执行读文件命令,代码更短:
# 匹配INPUT行,替换为cat对应文件的执行结果 sed -E 's/^INPUT ([^ ]+)$/cat "\1.txt"/e' 你要处理的目标文件
要直接修改原文件只需要加-i参数:
sed -i -E 's/^INPUT ([^ ]+)$/cat "\1.txt"/e' 你要处理的目标文件
注意事项
- 如果你的
INPUT标记不是独占一行,而是出现在行内任意位置,只需要把正则匹配规则里的^(行首)和$(行尾)去掉,改成/INPUT ([^ ]+)/即可。 - 如果文件名可能包含空格,可以把awk里的取值逻辑改成
filename = substr($0, 7) ".txt",直接取INPUT之后的所有内容作为文件名即可。 - 不建议直接用sed的
s命令做字符串替换:几百行的文件内容大概率包含换行、&、\、/等sed的特殊字符,提前转义的成本非常高,远不如直接读文件的方案高效。
内容的提问来源于stack exchange,提问作者Village
相关产品推荐
相关产品推荐

