如何逐行匹配file2规则,将file1命中内容替换为file3对应行内容
问题根因
之前执行的sed、Vim替换命令未生效,核心原因有两点:
[、]属于正则表达式特殊元字符,直接写在匹配规则中不会被识别为普通方括号,必须加反斜杠转义才能匹配字面量- 单引号包裹的sed脚本内反引号不会被解析执行,
sed -i 's/`cat file2.txt`/`cat file3.txt/g' file1.txt的写法本身不符合语法规则,无法实现逐行对应匹配替换的逻辑
可行方案
方案1:单条sed命令(适配当前场景,无需依赖file2/file3)
针对当前Obsidian格式图片转Markdown外链的固定场景,直接执行下面的命令即可原地修改file1.txt:
sed -i 's#!\[\[Pasted image \(.*\.png\)\]\]##g' file1.txt
命令逻辑:
- 所有方括号前加
\转义,让正则匹配字面意义的[[、]]字符 - 用
\(.*\.png\)捕获括号内的图片文件名,替换部分用\1引用捕获到的文件名,直接拼接成目标Markdown图片格式
方案2:逐行读取file2/file3对应替换(通用场景)
如果后续替换规则变动,需要严格遵循「file2第N行作为匹配串、替换为file3第N行内容」的逻辑,可以用awk实现,适配任意对应替换场景:
awk ' NR==FNR { if (FILENAME == ARGV[1]) match_pattern[FNR] = $0 else replace_str[FNR] = $0 next } { for (line_num in match_pattern) { gsub("!\\[\\[Pasted image " match_pattern[line_num] "\\]\\]", replace_str[line_num]) } print } ' file2.txt file3.txt file1.txt > tmp_file && mv tmp_file file1.txt
命令逻辑:
- 按顺序先读file2,把每一行内容存入匹配规则数组,行号作为索引
- 再读file3,把每一行内容存入替换字符串数组,相同行号和匹配规则一一对应
- 最后逐行处理file1,遍历所有匹配规则完成替换,结果写入临时文件后覆盖原文件
方案3:Vim内直接替换
如果习惯在Vim编辑器内操作,打开file1后执行下面的替换命令即可,注意转义特殊字符:
%s#!\[\[Pasted image \(.*\.png\)\]\]##g
执行完成后输入:w保存即可得到预期结果。
替换后效果
执行任意方案后,file1.txt内容和预期完全一致:
34 │  35 │ 36 │  37 │ 38 │  39 │ 40 │ 
内容的提问来源于stack exchange,提问作者c0rvu5
相关产品推荐
相关产品推荐

