通过在bash中使用sed,在特定的模式正则表达式匹配之后从文件插入内容

时间:2018-12-11 09:51:24

标签: regex sed

我想在特定文本之前在文本文件中插入多行。我想使用正则表达式来选择特定的文本,文本是这样的:

//**insert_yannyann*//

『// ** insert_yannyann * //』位于b.txt中,而b.txt就是这样

...

//**insert_yannyann*//

...

a.txt就像这样:

1234
5678
9101

要在b.txt中的文本模式之前插入a.txt文本文件,我在ubuntu 18.04 bash命令中尝试了此正则表达式。

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_yannyann\b)]*?\*\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_yannyann\b)]*?\*\s*//?

我不确定不同编程语言中的正则表达式法规是否相同,有人可以解释为什么它不正确吗?

1 个答案:

答案 0 :(得分:1)

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一次吞噬整个文件。
  • Perl变量$.包含与该用例中的输入文件号相同的输入行号。使用此值,我们可以切换a.txtb.txt的处理。
  • $replace = $_语句将变量$replace分配给a.txt的内容。
  • 最重要的部分是正则表达式s#(?=//\*\*insert_yannyann\*//)#$replace#gPerl regex支持使用(?=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放在&之前会导致在匹配的模式之前