きれいなテキストファイルを使用しようとしています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
:パターンスペースを印刷します。このとき、パターン空間には1loss
行、その前行、その後の2行が含まれる。s/.*//
:パターン空間を消去します。x
:パターンスペースを変更してスペースを維持します。このコマンドは、loss
一致するかどうかに関係なく実行されます。- 一致するものがあれば、中かっこ内のすべてのコマンドを
loss
実行し(上記にリストされている)、パターンスペースは空です。したがって、予約済みスペースは空白に設定されます。 (これは確かではありません。{
}
本物必ず必要なことですが、おそらく良い考えでしょう。 ) - 一致するものがない場合は、
loss
パターンスペースに現在の行が含まれているため、現在の行は予約済みスペースに配置されます。
- 一致するものがあれば、中かっこ内のすべてのコマンドを
私が知っている限り、入力が説明通りであれば完璧に動作します。
- 入力の最初の行にが含まれている場合は、空の行と入力
loss
の最初の3行(つまり、そのloss
行とそれに続く2行)が印刷されます。 入力の最後の行または2行目にが含まれている場合、その行の後に
loss
2行がないため、印刷されません。これは、ファイルの終わりに達するとコマンドシーケンスが中断されるloss
ためです。その行、その前の行、およびその後の(単一の)行(ある場合)を印刷してこの状況を処理するには、次のようにしますsed
。loss
sed -n '/loss/ { x; G; p; n; p; n; p; s/.*// }; x' pingFailed.txt > pingFailed1.txt
"after" 2行をそれぞれ読んで印刷します。