如何使用 awk 在文件中间插入一行,给定一个在 AFTER 或 BEFORE 处插入的搜索模式

如何使用 awk 在文件中间插入一行,给定一个在 AFTER 或 BEFORE 处插入的搜索模式

我想在文件中间插入一些文本。要插入的文本应该位于特定行之后,例如“ <begin>”。我不知道行号,也不知道要插入的文本的行数。我只知道在“”行之后<begin>我需要插入另一个文件的内容。

我只是不知道如何使用 awk 来做这样的事情。

谢谢 :-)

答案1

使用以下代码创建一个文件。您可以将其另存为:
insertfile.awk(或任何您想要的名称)

    BEGIN{
        while ( (getline < outerfile) > 0 )
        {
            if ($0 == matchline) 
            {  
                if ("after" == includematch)
                {
                    print
                }
                if ("before" == includematch)
                {
                    holdline = $0
                }
                  while ( (getline < innerfile) > 0) 
                {
                    print
                }
                close(innerfile)
                if ("before" == includematch)
                {
                     print holdline
                     holdline = ""
                }
            }
            else
            {
                print
            }
        }
        close(outerfile)
    }

使用的 awk 命令行参数是:

-v outerfile="file1.txt"    This is the name of the file you are searching (and printing).
-v innerfile="file2.txt"    This is the name of the file you will insert when you file a match
-v matchline="Search Text"  This is what you will search for as a line in file1.txt
-v includematch="before"    Optional: insert the file, before the matchline
-v includematch="after"     Optional: insert the file, after the matchline
-v includematch=""          If "includematch" is any other value, or empty, or not present, 
                            then insert the file, REPLACING matchline.
-f "insertfile.awk"         This is the name of the awk command file.

然后,要使用它,你可以像这样调用 awk:

awk -v outerfile="file1.txt" -v innerfile="file2.txt" -v matchline="cat" -f "insertfile.awk"  
(Read and print "file1.txt".  Search for line containing only "cat". REPLACE "cat" lines with "file2.txt"  

awk -v outerfile="file1.txt" -v innerfile="file2.txt" -v matchline="dog" -v includematch="before" -f "insertfile.awk"
(Read and print "file1.txt".  Search for line containing only "dog". Insert "file2.txt" Before matched line.

awk -v outerfile="file1.txt" -v innerfile="file2.txt" -v matchline="bird" -v includematch="after" -f "insertfile.awk"
(Read and print "file1.txt".  Search for line containing only "bird". Insert "file2.txt" After matched line.

在 awk 脚本中,你可以像这样编辑它:

Change $0 to $1 or $2 or other to match a specific word instead of the whole line.  
"hard-code" the file-names instead of outerfile and innerfile if you wish.

如果您希望将输入数据“传输”到脚本中而不是从文件中获取,请像这样编辑 insertfile.awk 脚本:

        {
            if ($0 == matchline) 
            {

                if ("after" == includematch)
                {
                    print
                }
                if ("before" == includematch)
                {
                    holdline = $0
                }

                while ( (getline < innerfile) > 0) 
                {
                    print
                }
                close(innerfile)

                if ("before" == includematch)
                {
                     print holdline
                     holdline = ""
                }

            }
            else
            {
                print
            }
            close(outerfile)
        }

然后,要使用它,你可以像这样调用 awk:

type "somefile.txt" | awk -v innerfile="file2.txt" -v matchline="cat" -f "insertfile.awk"  
(Read and print STDIN.  Search for line containing only "cat". REPLACE "cat" lines with "file2.txt"  

type "anyfile.txt" | awk -v innerfile="file2.txt" -v matchline="dog" -v includematch="before" -f "insertfile.awk"
(Read and print STDIN.  Search for line containg only "dog". Insert "file2.txt" Before matched line.

type "otherfile.txt" | awk -v innerfile="file2.txt" -v matchline="bird" -v includematch="after" -f "insertfile.awk"
(Read and print STDIN.  Search for line containg only "bird". Insert "file2.txt" After matched line.

答案2

/<begin>/{
    insert_file("before_file.html")
    print $0
    insert_file("after_file.html")
    next
}
{
    print $0
}

你必须编写insert_file如下函数

function insert_file(file) {
    while (getline line <file)
        print line
    close(file)
}

请注意,当 before_file 和 after_file 相同时,这个确切版本似乎无法在我的 Mac 上按预期工作……我只得到了第一个副本。这可能与未能关闭文件有关。我会调查一下。是的,这对于文件来说是必要的close,一般来说,为了良好的实践,应该这样做。


此外,我认为这可能更容易sed......

用于插入文件关键线

sed '/<begin>/r after_file.html' input_file

之前插入文件稍微复杂一点,

 sed -n -e '/^function/r before_file.html' -e 'x' -e 'p' input_file

因此你可以使用类似

/^function/r before_file.html
x
p

sed -n -f script input_file

答案3

Perl 是 awk 的大哥。

perl -p -i -e 'print "some text\n" if /<begin>/' filename

如果您有多个 <begin>,那么它将需要修改。

编辑:哦,你想插入一个文件

perl -MFile::Slurp -p -i -e 'print read_file("file2") if /<begin>/' filename

(测试成功但你可能需要cpan File::Slurp先这么做。)

相关内容