AWK-搜索模式-将其添加为变量-搜索不是变量的下一行并打印它+变量

AWK - Search for a pattern-add it as a variable-search for next line that isn't a variable & print it + variable

我有给定的文件:

application_1.pp

application_2.pp

    #application_2_version => '1.0.0.1-r1',
    application_2_version => '1.0.0.2-r3',

application_3.pp

    #application_3_version => '2.0.0.1-r4',
    application_3_version => '2.0.0.2-r7',

application_4.pp

application_5.pp

    #application_5_version => '3.0.0.1-r8',
    application_5_version => '3.0.0.2-r9',

我希望能够读取此文件并搜索字符串

".pp"

找到该字符串后,它将该行添加到一个变量中并存储它。 然后它读取文件的下一行。如果它遇到以 # 开头的行,它会忽略它并移到下一行。

如果遇到不包含“.pp”且不以#开头的行,它应该在新文件中最后存储的变量旁边打印出该行。

输出将如下所示:

application_1.pp
application_2.pp    application_2_version => '1.0.0.2-r3',  
application_3.pp    application_3_version => '2.0.0.2-r7',
application_4.pp
application_5.pp    application_5_version => '3.0.0.2-r9',

我想用 awk 来实现。如果有人知道如何做到这一点,并且这是一个简单的解决方案,如果他们可以与我分享,我会很高兴。如果它更复杂,那么了解我需要了解 awk 中的哪些内容以便知道如何执行此操作(数组、变量等)会很有帮助。甚至可以用 awk 实现还是需要其他工具?

谢谢,

我会说

awk '/\.pp/ { if(NR != 1) print line; line = [=10=]; next } NF != 0 && substr(, 1, 1) != "#" { line = line [=10=] } END { print line }' filename

其工作原理如下:

/\.pp/ {                                # if a line contains ".pp"
  if(NR != 1) {                         # unless we just started
    print line                          # print the last assembled line
  }
  line = [=11=]                             # and remember this new one
  next                                  # and we're done here.
}

NF != 0 && substr(, 1, 1) != "#" {    # otherwise, unless the line is empty
                                        # or a comment
  line = line [=11=]                        # append it to the line we're building
}

END {                                   # in the end,
  print line                            # print the last line.
}

你可以使用 sed:

#n
/\.pp/{
    h
    :loop
    n
    /[^#]application.*version/{
        H
        g
        s/\n[[:space:]]*/\t/
        p
        b
    }
    /\.pp/{
        x
        p
    }
    b loop
}

如果将其另存为 s.sed 和 运行

sed -f s.sed file

你会得到这个输出

application_1.pp
application_2.pp    application_2_version => '1.0.0.2-r3',
application_3.pp    application_3_version => '2.0.0.2-r7',
application_4.pp
application_5.pp    application_5_version => '3.0.0.2-r9',

说明

#n 抑制正常输出。

一旦我们匹配 /\.pp/,我们将该行存储到 space 和 h 中,然后开始 loop

我们转到下一行 n

如果它匹配 /[^#]application.*version/,这意味着它不以 # 开头,那么我们将该行附加到保留 space 和 H,然后复制将 space 保留到模式 space 和 g,并将换行符和任何后续的白色 space 替换为制表符。最后我们用 p 打印,然后用 b

跳到脚本的末尾

如果它匹配/\.pp/,那么我们交换模式并用x保持spaces,然后用p打印。