Sed / Awk:用另一个文件

时间:2017-04-14 03:58:02

标签: awk sed

使用sed,我试图在脚本中替换第一次出现的评论,例如:

#ENTRYPOINT_CONTENT

将第二个文件($ file_content)的内容转换为另一个第三个文件(/base.sh)。

因此,根据许多文档,字符串应该非常简单,例如:

sed "s|\#ENTRYPOINT_CONTENT|$file_content|" /base.sh

但我总是会遇到如下错误:

sed: -e expression #1, char 23: unterminated s' command

或类似的消息,也试过不同的分隔符,即使用Awk代替,但没有成功,在搜索模式中转义#后似乎没问题,但我仍然无法将文件内容作为变量获取在Sed。

任何想法,无论是Sed还是Awk?

编辑:--------------------

@Sundeep @James Brown:

不想混合主题,也不要长篇大论:)对你的澄清请求的回复在本次编辑结束时以粗体显示,但为了详细说明上下文,我的案例是一个Docker入口点脚本bash(对于基本Docker镜像)名为/root/test/ base

#!/usr/bin/env bash

#ENTRYPOINT_CONTENT

if [[ -e "/root/test/custom" ]]; then

    printf "\n\n#ENTRYPOINT_CONTENT\n"  >> /root/test/custom

    # Code from whjm's reply below (actually works but appends shebangs from custom files)
    sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh

    mv /root/test/base2.sh /root/test/base.sh
    rm -f /root/test/custom

fi

我只是想让用户在特定路径上删除自己的另一个bash脚本(例如/root/test/ 自定义),例如:

#!/usr/bin/env bash
echo 'My 2nd bash code'

上面的第一个脚本( base )应该在#ENTRYPOINT_CONTENT位置插入自定义文件的内容(在基本脚本本身中,而不删除此搜索字符串),像这样:

#!/usr/bin/env bash

echo 'My 2nd bash code'

#ENTRYPOINT_CONTENT

if [[ -e "/root/test/custom" ]]; then

    printf "\n\n#ENTRYPOINT_CONTENT\n"  >> /root/test/custom

    # Code from whjm's reply below
    sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh

    mv /root/test/base2.sh /root/test/base.sh
    rm -f /root/test/custom

fi

如果其他用户稍后在同一路径上删除了另一个自定义脚本,我们应该将此第三个自定义脚本的代码添加如下:

#!/usr/bin/env bash
echo 'My 2nd bash code'
echo 'My 3rd bash code'
#ENTRYPOINT_CONTENT

if [[ -e "/root/test/custom" ]]; then
# ... and so on

关于来自自定义文件的shebang,如果将它们附加到基本文件,它不是真正的问题,来自@whjm的sed代码按预期工作但附加它们,而(令人惊讶的是)来自@的两个awk代码James Brown已经(优雅地)忽略了自定义文件中的所有其他shebang(可能因为它们也以#作为#ENTRYPOINT_CONTENT搜索字符串开头),但目前部分预先提供了代码,如:

#!/usr/bin/env bash
echo 'My 3rd bash code'
echo 'My 2nd bash code'
#ENTRYPOINT_CONTENT

虽然我试图将其添加为:

#!/usr/bin/env bash
echo 'My 2nd bash code'
echo 'My 3rd bash code'
#ENTRYPOINT_CONTENT

所以,总之,@Sundeep,如果你能给我一个awk代码的更新版本,那就完美了! :D (无法找到解决此问题的方法......)非常感谢。

您之前发布的代码:

NR==FNR { b=b (FNR==1?"":ORS) $0; next }
{ r=r (FNR==1?"":ORS) $0 } #ENTRYPOINT_CONTENT
END { sub(/\#[^\n]+/,r,b); print b}

1 个答案:

答案 0 :(得分:0)

如果你使用 GNU sed:

[STEP 101] # cat file1
11
xx // replace me
44
xx // don't replace me
55
[STEP 102] # cat file2
22
33
[STEP 103] # sed -e '0,/^xx/!b; /^xx/{ r file2' -e 'd }' file1
11
22
33
44
xx // don't replace me
55
[STEP 104] #