Sed用文件内容替换模式

时间:2014-12-08 16:06:52

标签: regex bash sed

我想用sed(我认为?)用文件内容替换模式。

实施例

文件1(主文件)

Hello <<CODE>>
Goodbye.

文件2(内容)

Anonymous person,
I am very nice. 

文件3(目标)

Hello Anonymous person,
I am very nice.
Goodbye.

现在,我正在使用此命令:

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

但是这会输出:

Hello
Anonymous person,
I am very nice.
Goodbye.

(请注意Hello之后的换行符)

  • 如果没有获取换行符,我怎么能这样做?
    • (请注意,file2可能包含各种内容:括号,换行符,引号,...)

5 个答案:

答案 0 :(得分:2)

使用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:s RS $0 - 以字符串s
  • 连接整个文件内容
  • next - 在第一个文件
  • 上阅读下一行,直至EOF
  • /<<CODE>>/ - 如果找到<<CODE>>的行,则执行该块
  • sub(/<<CODE>>/, s) - 将<<CODE>>替换为字符串s(数据file2
  • 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

答案 1 :(得分:1)

awk尽管可能更难阅读,但这可能是正确的方法。

为了比较,这是一个红宝石版本

ruby -ne 'BEGIN{@body=File.open("file2").read}; puts gsub(/<<CODE>>/,@body);' < file1

答案 2 :(得分:1)

你可以简单地用:

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

答案 3 :(得分:0)

我正在考虑一种解决方案,我们使用Bash来评估cat脚本之外的sed流程,但不幸的是,以下内容并不会立即生效file2包含换行符:

sed 's/<<CODE>>/'"$(cat file2)"'/' file1

它接受file2中的空格,但不接受新行,正如您在以下代码段中看到的那样,无论file2的内容如何都是如此:

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

但是,显然,这会在包含之前修改文件的内容,这简直太糟糕了。 : - (

因此,如果你想玩,你可以先将tr新行添加到一些奇怪的无法预料的角色,并在sed处理其剧本后将其翻译回来:

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

答案 4 :(得分:0)

Perl中的

 cat file1 | perl -e "open FH, qq(file2); \$f2=join '', <FH>; chomp \$f2; map {s/<<CODE>>/\$f2/g; print \$_} <STDIN>" > file3

(也许我不是最好的perl编码器)

直截了当。读取整个文件2,替换它,然后打印。