匹配一行,运行if语句,bash脚本

时间:2017-07-20 15:14:02

标签: bash

我不确定这是否已经存在,但我在尝试表达我想在搜索字段中完成的工作时遇到了一些麻烦。

说我有一个类似以下的文件

foo1
foo2
foo3
barbarbar
barbarbar
barbarbar
foo4
foo5
barbarbar
barbarbar
barbarbar
foo6
foo7

我想在“foo#”之后只获得除“foo#”之外的字段。我还希望打印“foo#”如果它后面有条形栏并且直到下一个“foo#”。示例输出将在下面。

foo3
barbarbar
barbarbar
barbarbar

foo5
barbarbar
barbarbar
barbarbar

2 个答案:

答案 0 :(得分:2)

看起来这个sed命令可以正常工作:

sed -n '/^foo[0-9]$/{N;:l;/\nfoo[0-9]$/{D;bl};p;b};p'

老实说,我很遗憾试图用sed做到这一点,结果难以理解。

/^foo[0-9]$/{     # if a line matches fooX
    N                # retrieve another line
    :l               # we'll jump to here later ; label l
    /\nfoo[0-9]$/{   # if the following line matches fooX too
        D                # discard the first line and consume another one
        bl               # jump back to l
    }                # at this point we have a fooX line followed by a non-fooX line
    p                # print what we've matched
    b                # stop processing this line (jump to the end of the script)
}                 # reached when the first line read doesn't match fooX
p                 # print the line

编辑:既然我已经这样做了,我注意到p;b部分可以删除,因为它会通过到达最后p来表现相同。如果我是一个不得不维持这个的可怜的灵魂,我想我宁愿在那里拥有它。

答案 1 :(得分:1)

我通常不想发布“未尝试过”的问题的答案,但我有一些时间在我的手上。我喜欢用awk这样的东西:

“状态机”方法:

awk '
    /foo/ && afterfoo != "" { print currentfoo; print afterfoo; afterfoo = "" }
    /foo/  { currentfoo = $0 }
    !/foo/ { afterfoo = afterfoo $0 "\n" }
    END    { if (afterfoo != "") {print currentfoo; print afterfoo} }
' file

“逆过程逆转”方法:

tac file | awk '
    !/foo/ { print; seenfoo = 0 }
    /foo/ && !seenfoo++
' | tac