根据模式

时间:2015-05-23 05:59:32

标签: regex awk sed

你能否建议使用sed / awk命令合并文件中以模式开头并以方括号结尾的行;匹配是可变的行号,并用右括号控制。

例如,对于以下输入,提取模式将pattern1作为开头,并以'}'

结束
blah blah
pattern1 {
blah blah 1
blah blah 2
blah blah 3
}
pattern1 {
blah blah 1
blah blah 2
}

预期输出

blah blah 
partern1 {blah blah 1 blah blah 2 blah blah 3}
partern1 {blah blah 1 blah blah 2}

3 个答案:

答案 0 :(得分:0)

这解决了你在awk中的问题,通过注册我们是否在一个模式的中间,并采取行动。鉴于您的输入文件名为input.txt:

awk '/{/ {
    inPattern=1
}
{
    if (inPattern) {
        # When in a pattern, print the line (because of printf, this is without the newline).
        printf "%s ",$0;
    } else {
        # Otherwise, just print the line.
        print;
    }
}
/}/ {
    inPattern=0

    # Do this to go to a new line.
    print ""
}' input.txt
祝你好运!

答案 1 :(得分:0)

使用GNU sed:

$ sed '/pattern1/ {:x; N; s/\n/ /; /}/! bx}' infile
blah blah
pattern1 { blah blah 1 blah blah 2 blah blah 3 }
pattern1 { blah blah 1 blah blah 2 }

说明:

/pattern1/ {    # Line matches pattern1
    :x          # Label to branch to
    N           # Add next line to pattern space
    s/\n/ /     # Replace newline with space
    /}/! bx     # If pattern space doesn't contain '}', branch to :x
}               # End of cycle: print pattern space

如果您想用变量替换pattern1,则必须以不同的方式引用:

$ var=pattern1
$ sed "/$var/ {:x; N; s/\n/ /; /}/! bx}" infile

答案 2 :(得分:0)

这里有一个可移植的解决方案(适用于GNU sed,OSX,FreeBSD等),虽然它适用于所有模式,而不仅仅是匹配/pattern1/的部分。:

sed -ne '/{/{;x;/}/d;p;x;h;d;}; /}/! {;H;d;}; /}/{;H;x;s/\n/ /g;};p' file

为便于阅读而破解,脚本如下:

  • /{/{; - 对于任何包含左括号({)的行...
    • x;/}/d;p;x;h;d;}; - 打印..除非它是一个右大括号,然后将其添加到我们的手中。
  • /}/! {;H;d;}; - 对于没有右括号的任何行,将其附加到我们的保留。
  • /}/{;H;x;s/\n/ /g;}; - 对于任何带有右括号的行,附加它,交换保持和模式空格,并用换行代替空格。
  • p - 并打印结果(因为我们有-n作为sed选项。)

适用于您的测试输入数据,我还没有对其进行测试。

请注意,如果模式中存在嵌入模式,则肯定会失败。要处理这种情况,您需要使用实际的语言,例如,它可以在遍历文件时跟踪嵌套级别。