在bash中使用sed,在特定模式regex匹配后插入文件中的内容



我想在特定文本之前插入文本文件中的多行。我想使用regex来选择特定的文本,文本如下:

//**insert_yannyann*//

『//**insert_yannyann*//』在b.txt中,b.txt就像一样

...
//**insert_yannyann*//
...

a.txt是这样的:

1234
5678
9101

为了在b.txt中的文本模式之前插入.txt文本文件,我在ubuntu 18.04 bash命令中尝试了这个regex。

sed -n -i -e '//**insert_yannyann*// /r a.txt' -e 1x -e '2,${x;p}' -e '${x;p}' b.txt

甚至我还尝试了另一种正则表达式模式。

sed -n -i -e '//?s**[(?=.*insert_yannyannb)]*?*s*//? /r a.txt' -e 1x -e '2,${x;p}' -e '${x;p}' b.txt

但是sed总是为我使用的错误正则表达式向我显示错误的消息。

我想把b.txt做成这样:

...
1234
5678
9101
//**insert_yannyann*//
...

我当然会通过一些在线正则表达式工具检查其中两个正则表达式是否正确,但我不明白为什么sed会向我显示错误的消息。

//**insert_yannyann*//
//?s**[(?=.*insert_yannyannb)]*?*s*//?

我不确定regex规则在不同的编程语言中是否相同,有人能解释为什么它不正确吗?

Perl可能不是您的选择,但值得一试。使用Perl,您可以说:

perl -0777 -ne 'if ($. == 1) {$replace = $_; next} s#(?=//**insert_yannyann*//)#$replace#g; print' a.txt b.txt > b_new.txt

b_new.txt保持:

...
1234
5678
9101
//**insert_yannyann*//
...

解释:

  • -0777选项会导致Perl一次擦除整个文件
  • CCD_ 5变量CCD_ 6保存与本用例中的输入文件号相等的输入行号。使用该值,我们可以切换a.txtb.txt的处理
  • $replace = $_语句将变量$replace分配给a.txt的内容
  • 最重要的部分将是正则表达式s#(?=//**insert_yannyann*//)#$replace#gPerl正则表达式支持使用(?=pattern)表示法的前瞻断言。由于有了这种功能,我们可以很容易地在指定模式之前插入内容

希望这能有所帮助。

编辑

使用AWK,您可以做类似的事情:

awk 'NR==FNR {replace = replace $0 RS; next}
{text = text $0 RS}
END {
print gensub(///**insert_yannyann*///, replace "&", "g", text)
}' a.txt b.txt > b_new.txt

关键是替换字符串(gensub()的第二个参数(是replace(a.txt的内容(和&(表示正则表达式匹配的字符串(的串联。将变量replace放在&之前会导致匹配模式之前的替换。

最新更新