如果它与后面的行匹配,则打印特定行

时间:2013-07-04 06:13:21

标签: linux perl bash sed awk

我有一个包含以下信息的日志文件:

    <msisdn>37495989804</msisdn>
    <address>10.14.14.26</address>
    <msisdn>37495371855</msisdn>
    <address>10.14.0.172</address>
    <msisdn>37495989832</msisdn>
    <address>10.14.14.29</address>
    <msisdn>37495479810</msisdn>
    <address>10.14.1.11</address>
    <msisdn>37495429157</msisdn>
    <address>10.14.0.213</address>
    <msisdn>37495275824</msisdn>
    <msisdn>37495739176</msisdn>
    <address>10.14.2.86</address>
    <msisdn>37495479840</msisdn>
    <address>10.14.1.12</address>
    <msisdn>37495706059</msisdn>
    <msisdn>37495619889</msisdn>
    <address>10.14.1.198</address>
    <msisdn>37495574341</msisdn>
    <address>10.14.1.148</address>
    <msisdn>37495391624</msisdn>
    <address>10.14.0.188</address>
    <msisdn>37495989796</msisdn>
    <address>10.14.14.24</address>
    <msisdn>37495835940</msisdn>
    <address>10.14.2.164</address>
    <msisdn>37495743249</msisdn>
    <address>10.14.2.94</address>
    <msisdn>37495674117</msisdn>
    <address>10.14.1.236</address>
    <msisdn>37495754536</msisdn>
    <address>10.14.2.120</address>
    <msisdn>37495576434</msisdn>
    <msisdn>37495823889</msisdn>
    <address>10.14.2.159</address>

有些行'msisdn'行后面没有'address'行,如下所示:

<msisdn>37495576434</msisdn>
<msisdn>37495823889</msisdn>

我想编写一个脚本,它只会输出没有'address'的行('msisdn'行)。预期产出:

<msisdn>37495275824</msisdn>
<msisdn>37495706059</msisdn>
<msisdn>37495576434</msisdn>

如果它与awk / sed一起使用,它将是完美的。 感谢。

4 个答案:

答案 0 :(得分:2)

awk的一种方式:

awk '/address/{p=0}p{print a;p=0}/msisdn/{a=$0;p=1}' log

答案 1 :(得分:0)

你可以使用pcregrep匹配下一行不是地址并使用awk显示它

pcregrep -M '(.*</msisdn>)\n.*<msi' | awk 'NR % 2 == 1'

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -r '$!N;/(<msisdn>).*\n.*\1/P;D' file

这将在模式空间中读取2行,并尝试在两行中匹配模式<msisdn>。如果模式匹配,则打印出第一行。然后删除第一行并再次开始该过程,但是由于模式空间包含第二行(现在是第一行),因此自动读取行是放弃的,并且过程从$!N开始。

答案 3 :(得分:0)

Perl有自己的方法来做到这一点:

perl -lne 'if($prev && $_!~/\./){print $prev}unless(/\./){$prev=$_}else{undef $prev}' your_file

下面测试:

> perl -lne 'if($prev && $_!~/\./){print $prev}unless(/\./){$prev=$_}else{undef $prev}' temp
<msisdn>37495275824</msisdn>
<msisdn>37495706059</msisdn>
<msisdn>37495576434</msisdn>
>