一致するパターンの後の行の部分のみを返す


109

したがって、ファイルを開いcatgrepから一致する行を取得するために使用するのは、現在扱っている特定のログセットを操作しているときだけです。行をパターンに一致させる方法が必要ですが、一致後の行の部分のみを返す必要があります。試合の前後の部分は一貫して変化します。sedまたはを使用して遊んでawkいますが、一致する前に部分を削除するか、一致した後に部分を返すために行をフィルタリングする方法を見つけることができませんでした。これは、フィルタリングする必要がある行の例です。

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

私がする必要があるのは、特定のノードが何回ストールしたかを調べることです(「ストール」後の各コロンの前の部分で示されます。失速していないので、私は助けにはなりません。

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


@Gilles、奇妙なことに、検索したときにポップアップが表示されませんでしたが、最終的に一緒に使用したタイトルは使用しませんでした...しかし、タイトルの下の画面には表示されませんでした。とにかく、それはさておき、最初の単語ではなく、試合後の行全体が必要ですが、あまり変更しないかもしれませんが、それは私が望む場所に行くかもしれません。
MaQleod

そのタイトルは吸った。私はあなたのものを盗みました。sed解決策を取り、空白を特別に扱わないでください。
ジル

@Gilles、それはどうすればいいかわからない。私はまだsedを学んでいます。
MaQleod


1
@ shaa0601私はあなたの質問を理解していません。フォーマットなしでコメントをフォローすることは特に難しいです。新しい自己完結型の質問をします。
ジル14

回答:


141

そのための標準的なツールはになりますsed

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

詳細な説明:

  • -n デフォルトでは何も印刷しないことを意味します。
  • -e sedコマンドが続きます。
  • s パターン置換コマンドです。
  • 正規表現^.*stalled:は、探しているパターンに加えて、先行するテキスト(一致は行の先頭から始まると言う.*イニシャル^を持つ任意のテキストを意味する)に一致します。stalled:行で複数回発生する場合、これは最後の発生と一致することに注意してください。
  • 一致、つまり、までの行のすべてstalled:が空の文字列に置き換えられます(削除されます)。
  • p変換された行を印刷する最後の手段。

一致部分を保持する場合は、後方参照を使用します。\1置換部分\(…\)では、パターン内のグループ内にあるものを指定します。ここstalled:で、交換部品に再度書き込むことができます。この機能は、探しているパターンが単純な文字列よりも一般的な場合に役立ちます。

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

場合によっては、一致後の行の一部を削除することがあります。.*$パターンの最後(.*行の最後に続く任意のテキスト)に含めることで、一致に含めることができます$。置換テキストで参照するグループにその部分を配置しない限り、行の終わりは出力に含まれません。

グループおよび後方参照のさらなる説明として、このコマンドは、一致する前の部分と一致した後の部分を交換します。

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

最初の2つの例を試しましたが、ハングしているようです。エラーメッセージも新しいプロンプトも表示されず、何も表示されません。
MaQleod

2
@MaQleodああ、標準入力での入力を待っています。ここは、リダイレクトしていないのでターミナルです。ここでsed … <messagesは、ファイルからデータを処理するため、入力のリダイレクトを行います。別のコマンドで生成されたデータを処理するには、パイプを使用しますsomecommand | sed …
ジル

1
そこに一日の終わりの停電。コマンドは完璧に動作します、ありがとう。
MaQleod

1
これまで見た中で最高のsedの説明-ありがとう!
ジョンワズワース

1
@ungalcrys何の短いバージョン?これは私の答えのどのコマンドとも同等ではありません。Linuxに固有のものであり、macOSなどの他のシステムでは機能しないため、ここからは何のメリットも得られないsed 's/^.*stalled//'ので、それを書くことをお勧めし-rます。
ジル

72

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

例えば:

grep -o 'stalled.*'

Gillesの2番目のオプションと同じ結果になります。

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

-oフラグが返さ--only-matchingもちろん- -通常のgrepによって行われる行全体を式の一部を、そうではありません。

出力から「停止」を削除するには、カットする3番目の標準ツールを使用できます。

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

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


1
-oオプションについて言及してくれてありがとう!を改行としてgrep認識しないことを指摘したかった\nので、最初の例は最初のn文字にのみ一致します。たとえばecho "Hello Anne" | grep -o 'A[^\n]*'、文字列を返しますA。ただし、改行を除くすべての文字に一致するためecho "Hello Anne" | grep -o 'A.*'、期待されるを返します。Anne.
アダムラマー

1
cut区切り文字-d':'を囲む引用符は@poigeによって削除されることに注意してください。引用符を使用すると、たとえば-d' 'またはを使用して覚えやすくなります-d';'
アンヴァンロッサム

あなたの発見によると、引用符も一緒に使用することを覚えておくのは簡単-f 2です。真剣に、なぜですか?
-poige

コロン;ではなくセミコロンのような区切り文字は、:引用符を付けないと解釈が異なるためです。もちろんそれは論理的な振る舞いですが、それでも筋肉の記憶に頼るのが好きです。区切り文字を1回引用するのは好きではありませんが、もう1回は引用しません。先ほど言ったように、個人的な好みです。覚えやすいです。
アンヴァンロッサム

一部である期間.*が必要であるが、私のためによく働い: cat filename | grep 'Return only this line xyz text' | grep -o 'xyz.*' リターンxyz text
ロンを

4

ifconfig | grep eth0 | cut -f3- -d:はこれを取っていました

    [root@MyPC ~]# ifconfig
    eth0  Link encap:Ethernet  HWaddr AC:B4:CA:DD:E6:F8
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:78998810244 errors:1 dropped:0 overruns:0 frame:1
          TX packets:20113430261 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:110947036025418 (100.9 TiB)  TX bytes:15010653222322 (13.6 TiB)

そして、このように見せます

    [root@MyPC ~]# ifconfig | grep eth0 | cut -f3- -d:
    C4:7A:4D:F6:B8

2
これは質問に答えますか?
スティーブンラウフ

1
を使用できcat /sys/class/net/*/address、解析は不要です。
アンヴァンロッサム

1

検討した別の標準的なツールawkは、次の行で使用できます。

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

詳細な説明:

  • -F行の区切り、つまり「停止」を定義します。区切り文字の前のすべてがでアドレス指定され$1、その後のすべてがでアドレス指定されます$2
  • /reg-ex/ 一致する正規表現、この場合は「停止」を検索します。
  • {print $<n>}-n列を印刷します。区切り文字は失速していると定義されているため、失速後のすべてが2番目の列と見なされます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.