我有一个包含以下信息的日志文件:
<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一起使用,它将是完美的。 感谢。
答案 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>
>