Regex 用文件内容替换模式

Regex 用文件内容替换模式,regex,bash,sed,Regex,Bash,Sed,我想使用sed(我想?)用文件内容替换模式 例子 文件1(主文件) 文件2(目录) 文件3(目标) 现在,我正在使用以下命令: sed "/<<CODE>>/{r file2 :a;n;ba}" file1 | \ sed "s/<<CODE>>//g" > \ file3 但这会产生: Hello Anonymous person, I am very nice. Goodbye. (注意H

我想使用
sed
(我想?)用文件内容替换模式

例子 文件1(主文件) 文件2(目录) 文件3(目标)
现在,我正在使用以下命令:

sed "/<<CODE>>/{r file2
:a;n;ba}" file1            | \
    sed "s/<<CODE>>//g"    > \
    file3
但这会产生:

Hello
Anonymous person,
I am very nice.
Goodbye.
(注意
Hello
后面的换行符)

  • 我怎么能在没有新线的情况下做到这一点?
    • (请注意,
      file2
      可能包含各种内容:方括号、换行符、引号等)

    • 使用awk要简单得多:

      awk 'FNR==NR{s=(!s)?$0:s RS $0;next} /<<CODE>>/{sub(/<<CODE>>/, s)} 1' file2 file1
      Hello Anonymous person,
      I am very nice.
      Goodbye.
      
      说明:

      • FNR==NR
        -对输入中的第一个文件执行此块,即
        file2
      • s=(!s)?$0:srs$0
        -将整个文件内容连接到字符串
        s
      • next
        -读取下一行,直到第一个文件的
        EOF
      • /
        /
        -如果找到带有
        的行,则执行该块
      • sub(/
        /,s)
        -将
        替换为字符串
        s
        (文件2的数据)
      • 1
        -打印输出

      编辑:非正则表达式方式:

      awk 'FNR==NR{s=(!s)?$0:s RS $0; next}
           i=index($0, "<<CODE>>"){$0=substr($0, 1, i-1) s substr($0, i+8)} 1' file2 file1
      

      虽然awk可能更难阅读,但它可能是正确的方法

      为了比较起见,这里有一个ruby版本

      ruby -ne 'BEGIN{@body=File.open("file2").read}; puts gsub(/<<CODE>>/,@body);' < file1
      
      ruby-ne'BEGIN{@body=File.open(“file2”).read};放置gsub(//,@body);'<文件1
      
      我正在考虑一种解决方案,我们使用Bash来评估
      cat
      进程,而不是限定
      sed
      脚本的单引号,但不幸的是,一旦
      文件2
      包含换行符,以下内容就无法正常工作:

      sed 's/<<CODE>>/'"$(cat file2)"'/' file1
      
      它接受
      file2
      中的空格,但不接受换行符,正如您在下面的一段代码中看到的那样,无论
      file2
      的内容如何,它都可以正常工作:

      sed 's/<<CODE>>/'"$(cat file2 | tr -d '\n')"'/' file1
      
      但是,很明显,这会在包含之前修改文件的内容,这很糟糕-(

      因此,如果你想玩,你可以先把新行翻译成一些奇怪的、意想不到的角色,然后在sed完成脚本后再翻译回来:

      sed 's/<<CODE>>/'"$(cat file2 | tr '\n' '\3')"'/' file1 | tr '\3' '\n'
      

      Perl
      中还不错:

       cat file1 | perl -e "open FH, qq(file2); \$f2=join '', <FH>; chomp \$f2; map {s/<<CODE>>/\$f2/g; print \$_} <STDIN>" > file3
      
      catfile1 | perl-e“openfh,qq(file2);\$f2=join';chomp\$f2;map{s/
      /\$f2/g;print\$\}>file3
      
      (也许我不是最好的perl程序员)


      这是直截了当的。读入整个文件2,替换它,然后打印。

      您只需执行以下操作:

      awk '{gsub("<<CODE>>", filetwo)}1' filetwo="$(<file2)" file1
      

      awk'{gsub(“
      ”,filetwo)}1'filetwo=“$(它必须是
      sed
      )?您可以使用
      perl
      ruby
      python
      ?脚本的其余部分在
      bash
      中,因此任何不需要调用/创建新(脚本)的内容都可以文件很受欢迎。但是一个一行的perl或ruby命令可以工作,对吗?如果你知道如何编写它,那么是的:-)。我对
      perl
      /
      ruby
      的知识有限。我仍在思考。我不确定perl/ruby是否更好,但它似乎可以打开一些局面。我想你和我对simple有不同的定义;-)。尽管如此,它仍然完美无瑕。@EtienneBruines:lol:)希望我的解释能让我们的定义更接近。请随意提问以进一步解释。这确实打破了使用
      &
      -字符的习惯(即
      &
      -字符被
      替换)文件2.刚刚发现
      sed
      要求我转义
      &
      -字符。可能这是相关的。
      sed 's/<<CODE>>/'"$(cat file2 | tr '\n' '\3')"'/' file1 | tr '\3' '\n'
      
       cat file1 | perl -e "open FH, qq(file2); \$f2=join '', <FH>; chomp \$f2; map {s/<<CODE>>/\$f2/g; print \$_} <STDIN>" > file3
      
      awk '{gsub("<<CODE>>", filetwo)}1' filetwo="$(<file2)" file1