sedで一致するものが見つかった場合は、2行をスキップします。

sedで一致するものが見つかった場合は、2行をスキップします。

きれいなテキストファイルを使用しようとしていますsed

pingを実行してテキストファイルに出力するプログラムがあります。プログラムは、ping出力の後にタイムスタンプを追加して、いつ失敗するのかを知ることができます。

pingの失敗と下の2行、上の行を除くすべてのエントリを削除する必要があります。私の表現に合ったら、sed次の2行をスキップする方法はありませんか?

例:

--- 8.8.8.8 ping statistics ---
rtt min/avg/max/mdev = 18.001/21.159/26.006/2.959 ms
Tue 26 Nov 09:39:56 GMT 2019


--- 4.2.2.2 ping statistics ---
10 packets transmitted, 9 received, 10% packet loss, time 18034ms
rtt min/avg/max/mdev = 20.560/34.013/70.076/17.428 ms
Tue 26 Nov 09:40:46 GMT 2019

--- 8.8.8.8 ping statistics ---
rtt min/avg/max/mdev = 17.510/20.543/26.618/2.317 ms
Tue 26 Nov 09:41:04 GMT 2019

以下を使用する場合: sed '/loss/!d' pingFailed.txt > pingFailed1.txt

その後、私の出力は次のようになります。

10 packets transmitted, 4 received, 60% packet loss, time 18103ms
10 packets transmitted, 3 received, 70% packet loss, time 18107ms

ただし、出力は次のようになります。

--- 4.2.2.2 ping statistics ---
10 packets transmitted, 9 received, 10% packet loss, time 18034ms
rtt min/avg/max/mdev = 20.560/34.013/70.076/17.428 ms
Tue 26 Nov 09:40:46 GMT 2019

どうすればこれを行うことができますか(好ましくはからsed)?

答え1

この方法があなたに合っているかどうか教えてください。

grep -B1 -A2 "loss" pingFailed.txt > pingFailed1.txt

出力:

--- 4.2.2.2 ping statistics ---
10 packets transmitted, 9 received, 10% packet loss, time 18034ms
rtt min/avg/max/mdev = 20.560/34.013/70.076/17.428 ms
Tue 26 Nov 09:40:46 GMT 2019

「損失」パターンのある行を見つけます。

grep "loss"

一行を印刷する第二前に:

-B1

2行を印刷する後:

-A2

答え2

これを行うことができるはずですsed

sed -n '/loss/ { x; G; N; N; p; s/.*// }; x' pingFailed.txt > pingFailed1.txt

説明する:

  • -n:何も自動的に印刷しません。ある場合のみ印刷します。印刷コマンド。
  • /loss/ { … }: ""を含む行が表示されたら、中括弧内のコマンドを実行しますloss
  • x:パターンスペースを変更してスペースを維持します。パターン空間には、今読んだ行が含まれています。スポイラー警告:前の行を含めるためにスペースが予約されています。このコマンドを実行した後、パターンスペースには前の行が含まれ、予約されたスペースには現在の行が含まれます。
  • G:予約済みスペースの内容を取得し、パターンスペースに追加します(その間に改行を挿入)。このコマンドの後には、パターン空間に前の行と現在の行(つまり、このloss行とその前の行)が含まれます。
  • N:入力から別の行を読み取り、それらをパターンスペースに追加します(それらの間に改行を挿入)。
  • p:パターンスペースを印刷します。このとき、パターン空間には1  loss行、その前行、その後の2行が含まれる。
  • s/.*//:パターン空間を消去します。
  • x:パターンスペースを変更してスペースを維持します。このコマンドは、loss一致するかどうかに関係なく実行されます。
    • 一致するものがあれば、中かっこ内のすべてのコマンドをloss実行し(上記にリストされている)、パターンスペースは空です。したがって、予約済みスペースは空白に設定されます。 (これは確かではありません。{}本物必ず必要なことですが、おそらく良い考えでしょう。 )
    • 一致するものがない場合は、lossパターンスペースに現在の行が含まれているため、現在の行は予約済みスペースに配置されます。

私が知っている限り、入力が説明通りであれば完璧に動作します。

  • 入力の最初の行にが含まれている場合は、空の行と入力lossの最初の3行(つまり、そのloss行とそれに続く2行)が印刷されます。
  • 入力の最後の行または2行目にが含まれている場合、その行の後にloss2行がないため、印刷されません。これは、ファイルの終わりに達するとコマンドシーケンスが中断されるlossためです。その行、その前の行、およびその後の(単一の)行(ある場合)を印刷してこの状況を処理するには、次のようにしますsedloss

    sed -n '/loss/ { x; G; p; n; p; n; p; s/.*// }; x' pingFailed.txt > pingFailed1.txt
    

    "after" 2行をそれぞれ読んで印刷します。

関連情報