一致するパターンに続く行部分のみを返します

一致するパターンに続く行部分のみを返します

catしたがって、ファイルを開いてそれを使用して一致する行を取得すると、現在作業している特定のログセットに関する情報のみを取得できます。grep行をパターンに一致させる方法が必要ですが、行の一致部分のみを返します。ゲームの前後のセクションは絶えず変更されます。私は一致する部分を削除するために行をフィルタリングする方法を使用したか、一致した後に部分を返す方法を見つけることができません。どちらも機能しますsedawk以下は、フィルタリングする必要がある行の例です。

2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }

私に必要な部分は「低迷」以降のすべてです。

これの背景は、何かがどれだけ頻繁に停止するのかを知ることができるということです。

cat messages | grep stalled | wc -l

私がしなければならないことは、特定のノードが何度も停止したかどうかを調べることです(各コロンの前に「停止」の次の部分として表示されます。grepのみを実行すると(例:20:))、おそらくソフトエラーが発生した行を返すです。しかし、停止がないので役に立ちません。停止したノードで特定のノードを見つけることができるように、停止した部分をフィルタリングします。

すべての意図と目的のために、これは標準のGNUコアユーティリティを備えたfreebsdシステムですが、助けるために追加のインストールはできません。

答え1

一般的なツールはsed

sed -n -e 's/^.*stalled: //p'

上海:

  • -n基本的には何も印刷されないことを意味します。
  • -esed コマンドが続きます。
  • sパターン交換コマンドです。
  • 正規表現は、^.*stalled:探しているパターンと前のテキスト(.*すべてのテキストを意味し、最初の文字^は一致が行の先頭から始まることを意味します)と一致します。その行が複数回表示される場合は、stalled:最後の発生項目と一致します。
  • 一致する項目、つまり行までのすべての項目がstalled:空の文字列に置き換え(削除)されます。
  • 最後のp方法は、変換された行を印刷することです。

一致する部分を維持するには、逆参照を使用してください。\1置換部分のパターンにグループ内のコンテンツを割り当てます。\(…\)ここでは、stalled:置換セクションにもう一度書き込むことができます。この機能は、探しているパターンが単純な文字列よりも一般的な場合に便利です。

sed -n -e 's/^.*\(stalled: \)/\1/p'

時には、試合後にラインの一部を削除したい場合があります。.*$パターンの終わり(.*行の終わりの後のすべてのテキスト)に追加して、$一致に含めることができます。代替テキストで参照されているグループ内にセクションを配置しないと、行末は出力に表示されません。

グループと逆参照の追加の説明として、このコマンドは一致の前と後の部分を交換します。

sed -n -e 's/^\(.*\)\(stalled: \)\(.*\)$/\3\2\1/p'

部品を入手した後最初最後の文字列の代わりに文字列が表示される場合(文字列が複数回表示される行の場合)、通常の方法は文字列を改行(行に表示されない文字)に一度置き換えてから削除することです。改行文字より前のもの:

sed -n '
  /stalled: / {
    s//\
/
    s/.*\n//p
  }'

一部の実装では、最初のコマンドを作成することが可能ですsedが、これは標準/移植可能ではありません。ss//\n/

答え2

すでに使用している他の標準ツールgrep::

たとえば、

grep -o 'stalled.*'

Gillesの2番目のオプションと同じ結果:

sed -n -e 's/^.*\(stalled: \)/\1/p'

もちろん、通常はgrepを使用して実行されるように、この-oフラグは行全体ではなく式の一部を返します。--only-matching

出力から「stalled:」を削除するには、3番目の仕様ツールであるcutを使用できます。

grep -o 'stalled.*' | cut -f2- -d:

このcutコマンドは区切り文字を使用し、:最後までフィールド2を印刷します。もちろん、好みの問題ですが、cut構文が覚えやすいと思います。

答え3

考慮する別の標準ツールは、awk次の行で使用できます。

awk -F"stalled" '/stalled/{print $2}' messages

上海:

  • -Fこの行の区切り文字「ストール」を定義します。区切り記号の前の内容はすべてアドレス指定に使用され、区切り文字の後のすべての$1内容はアドレス指定に使用されます$2
  • /reg-ex/一致する正規表現を検索します。この場合、「停止しました」。
  • {print $<n>}- n個の列を印刷します。区切り文字は停止として定義されるため、停止後のすべての項目は2番目の列と見なされます。

答え4

Perl(別名Perl5)とRaku(以前のPerl6)の使用:

真珠:

perl -pe 's/^.*stalled: //; #leaves non-matching and/or blank lines intact

または:

perl -nE '/^.*stalled: (.*)/ and say $1;'  #removes non-matching lines

幸せ:

raku -pe 's/^.*stalled\:\s//;' #leaves non-matching and/or blank lines intact

または:

raku -ne '/^.*stalled\:\s (.*)/ and say ~$0;' #removes non-matching lines

出力(上記の2番目のPerlと2番目のRakuの例の場合):

12:6,31, 20:1 }

上記のコードは、2つの言語間で事実上同じです。最も重要な違いは、RakuでRaku正規表現エンジンが「文字通り理解する」には、数値ではなく/下線以外のすべての文字をエスケープする必要があることです。

他のニュアンスは次のとおりです。

  1. Rakuはキャプチャ番号を$ 0から始めるように変更します(Perlは$ 1で始まります)。
  2. Rakuは先行~チルダを使用して一致オブジェクトを文字列化します。
  3. Perlでは、-Eコマンドラインフラグを使用してこのsay機能を有効にする必要があります。

http://www.wall.org/~larry/natural.html
https://www.perl.org/
https://www.raku.org/

関連情報