仅在首次匹配后在另一个文件中添加文件内容

时间:2019-03-29 14:37:15

标签: bash sed

使用bash,我具有以下代码行,可以在特定匹配后将临时文件的内容添加到另一个文件中:

sed -i "/text_to_match/r ${tmpFile}" ${fileName}

我希望仅在FIRST比赛之后添加临时文件内容。

我尝试使用地址:

sed -i "0,/text_to_match//text_to_match/r ${tmpFile}" ${fileName}

但是它不起作用,说“ /”是未知命令。

如果我使用标准替换“ s / to_replace / with_this /”,则可以使地址正常工作,但是我不能使其与该sed命令一起工作。 如果我的sed命令以/而不是字母开头,看来我不能使用地址。

只要我只能将临时文件的内容插入到另一个文件一次,我就不会拘泥于地址。

4 个答案:

答案 0 :(得分:3)

您收到该错误消息是因为,如果您有一个地址范围(ADDR1,ADDR2),则不能在其后放置另一个地址:sed希望在那里有一个命令,而/不是命令。

您将在此处使用大括号:

$ seq 20 > file
$ echo "new content" > tmpFile
$ sed '0,/5/{/5/ r tmpFile
}' file

仅在带有'5'的第一行之后输出新文本

1
2
3
4
5
new content
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

我发现我需要在文件名后添加换行符。否则我会收到此错误

sed: -e expression #1, char 0: unmatched `{'

看来sed将整个行的其余部分作为文件名。

写起来可能更整洁

sed '0,/5/ {
    /5/ r tmpFile 
}' file

完全透明:除非常简单的任务外,我不使用sed。实际上,我会使用awk来完成这项工作

awk '
    {print} 
    !seen && $0 ~ patt {
        while (getline line < f) print line
        close(f)
        seen = 1
    }
'  patt="5" f=tmpFile file

答案 1 :(得分:2)

Glenn Jackman为OP尝试失败的原因提供了很好的答案。

继Glenn Jackman回答之后,如果您希望将命令放在一行上,则应使用分支,以便r命令位于末尾。

  

编辑{...}abcirt,{ {1}},w:之后可以是,可选的字符和另一个编辑命令。但是,将#编辑命令与s标志一起使用时,以这种方式在其后跟随另一个命令将产生未定义的结果。
[源:{{3 }}]

     

w命令解析文件名,直到行尾为止。如果找到空格,注释或分号,它们将包含在文件名中,从而导致意外的结果。
[来源:POSIX sed Standard] < / p>

给出:

r,R,w,W

答案 2 :(得分:1)

GNU sed还允许s///e进行炮击。因此,有一种使用Glenn的tmpFile和file的文件。

sed '0,/5/{//{p;s/.*/cat tmpFile/e}}' file

  • //重复上一个模式匹配(如果它长于/5/,则有帮助)
  • p打印匹配行
  • s/.*/cat tmpFile/e清空模式缓冲区,并在其中粘贴cat tmpFile shell命令,然后e执行该命令并将输出转储到流中

答案 3 :(得分:-1)

在第二个sed示例中,您将两个正斜杠放在一起,并且紧挨着。