在匹配另一个文件中的模式后插入内联文件中的文本

在匹配另一个文件中的模式后插入内联文件中的文本

我正在尝试使用 sed 获取文件的内容并将其插入到另一个文件中的匹配模式之后。我的问题非常类似于这个问题,但我希望内联插入文件的内容而不是在新行上插入。我怎样才能做到这一点?

使用我引用的示例问题,第一个答案正是我想要的;但是,我希望插入发生内联:

sed '/First/r file1.txt' infile.txt 

我想要插入的实际数据是一个 JSON 文件:

[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]

答案1

在您链接的问题中已经有了很好的awk答案,只需使用以下命令稍微修改一下printf即可,而不是print插入不带换行符的内容:

awk '/First/ { printf $0; getline < "File1.txt" }1' infile.txt

结果:

Some Text here
FirstThis is text to be inserted into the File.
Second
Some Text here

您可能需要在“First”之后添加空格或其他分隔符printf $0 " "; ...


如果插入的文件有很多行,则:

awk '/First/{printf $0; while(getline line<"File1.txt"){print line};next}1' infile.txt

结果:

Some Text here
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]
Second
Some Text here

答案2

您可以使用perl(获取文件内容并patternpattern+替换file content):

perl -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/' file.txt

添加-i就地编辑;g在每次 PAT(模式)出现后附加,例如:

perl -i -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/g' file.txt

另一种方式,使用ed

printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j ,p q | ed -s file.txt

要就地编辑,请替换,pw

 printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j w q | ed -s file.txt

可能没有人感兴趣这是如何工作的,但无论如何,printf将命令列表传递给ed

/PAT/s/PAT/&\             #   set address to first line matching PAT and
/                         #   split the line right after PAT
-                         #   set address one line before (return to the line matching PAT)
kb                        #   mark the current line
. r insert.txt            #   insert content of insert.txt after this line         
j                         #   join current line and the next
'b                        #   set  address to marked line (return to the line matching PAT)
j                         #   join current line and the next one
,p                        #   print file content
q                         #   quit editor

或者,不使用printfand |

ed -s file.txt <<< $'/PAT/s/PAT/&\\\n/\n-\nkb\n. r insert.txt\nj\n\'b\nj\nw\nq\n'

答案3

因此,要使这项工作可移植地工作会有点棘手sed- 您应该寻找cut和/或paste使用一些正则表达式前体在该上下文中生成其脚本 - 这是因为sed总是会插入一个\newlineead的输出r。尽管如此,使用 GNU sed

sed '/First/{x;s/.*/cat file/e;H;x;s/\n//}' <<\IN 
First
Second
Third
IN

每次遇到您的地址时都会e执行此操作。它在旧空间中执行此操作cat/First/h(无论如何 - 一个备用缓冲区 - 因为我改变x了它们,它实际上发生在曾经是h旧空间的模式空间中)以便保留行匹配的内容First,然后将cat的输出附加到您的行并删除中间的\newline。

输出:

First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
]
Second
Third

现在,如果您希望文件的全部内容适合之间一行的两个部分的工作方式必须略有不同,因为使用上面的命令我只需删除行之间的尾随换行符结尾匹配行的位置和文件的开头。不过,你也可以这样做:

sed '/First/{s//&\n/;h
         s/.*/{ cat file; echo .; }/e;G
         s/\(.*\).\n\(.*\)\n/\2\1/
}' <<\IN
Third
Second
First Second Third
Third
Second
First Second Third
IN

这会在匹配处用 ewline 字符分割行\n,将其保存在h旧空间中,executes cat(用其输出替换模式空间)G将保留空间的内容附加到另一个\newline 字符后面的新模式空间,然后重新排列\n行分隔符。

我确实echo .保留了所有尾随的\newline 字符file- 但如果这不是你的愿望(无论如何与你的例子不太相关)您可以不使用它,并在下面的替换中删除.前面的第一个。.\ns///

在重新排列模式空间之前,它看起来像这样:

^cat's output - any number of newlines.*.\nmatch on First\nrest of match$

输出:

Third
Second
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
] Second Third 
Third
Second
First[
    {
        "foo": "bar", 
        "baz": "biff",
        "data": [
            {
                "a": 1945619, 
                "b": [
                    {
                        "c": 512665, 
                        "d": "futz"
                    }
                ]
            }
        ]
    }
] Second Third

相关内容