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

时间:2015-06-13 17:57:05

标签: regex linux awk sed gawk

我有一个给定的文件:

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实现它还是另一种必要的工具?

谢谢,

2 个答案:

答案 0 :(得分:1)

我会说

awk '/\.pp/ { if(NR != 1) print line; line = $0; next } NF != 0 && substr($1, 1, 1) != "#" { line = line $0 } 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 = $0                             # and remember this new one
  next                                  # and we're done here.
}

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

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

答案 1 :(得分:1)

您可以使用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/后,我们会使用h将该行存储到保留空间,然后启动loop

我们使用n

转到下一行

如果它与/[^#]application.*version/匹配,意味着它不以#开头,那么我们会使用H将该行附加到保留空间,然后将保留空间复制到带有g的模式空间,并用换行符和任何后续空格替换选项卡。最后,我们使用p打印,然后使用b

跳到脚本的末尾

如果匹配/\.pp/,则我们交换模式并使用x保留空格,然后使用p进行打印。