-2

次の情報を含むログ ファイルがあります。

    <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

4 に答える 4

2

片道awk:

awk '/address/{p=0}p{print a;p=0}/msisdn/{a=$0;p=1}' log
于 2013-07-04T06:38:35.793 に答える
0

これはうまくいくかもしれません(GNU sed):

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

<msisdn>これは、パターン空間に 2 行を読み取り、2 行の両方でパターンを一致させようとします。パターンが一致すると、最初の行が出力されます。次に、最初の行が削除され、プロセスが再び開始されます。ただし、パターン スペースには 2 行目 (現在は最初の行) が含まれているため、行の自動読み取りは中止され、 からプロセスが開始され$!Nます。

于 2013-07-04T08:14:41.317 に答える
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>
> 
于 2013-07-04T08:32:28.993 に答える
0

pcgrep を使用して、次の行がアドレスではなく、awk show it を使用して一致させることができます

pcregrep -M '(.*</msisdn>)\n.*<msi' | awk 'NR % 2 == 1'
于 2013-07-04T06:33:33.943 に答える