web-dev-qa-db-ja.com

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

したがって、catを使用してファイルをプルし、grepを使用して一致する行を取得するのは、処理している特定のログセットを操作しているときだけです。行をパターンに一致させる方法が必要ですが、一致した後の行の部分を返すだけです。試合の前後の部分は常に変化します。私は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

特定のノードが停止した回数を確認する必要があります(「停止した」後の各コロンの前の部分で示されます。そのためにgrepだけ(つまり20 :)すると、ソフト障害のある行が返されることがありますが、ストールはありませんが、それは私には役に立ちません。ストールした部分のみをフィルタリングする必要があるので、ストールしたノードから特定のノードをgrepできます。

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

127
MaQleod

そのための標準的なツールは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'
_

すでに使用しているもう1つの正規ツール:grep

例えば:

grep -o 'stalled.*'

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

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

-oフラグは式の--only-matchingの部分を返すため、通常はgrepによって行われる行全体ではありません。

「stalled:」を出力から削除するには、3つ目の正規ツールであるカットを使用します。

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

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

83
Anne van Rossum

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
4
Luis Perez

awkと見なしたさらに別の正規ツールは、次の行で使用できます。

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

詳細な説明:

  • -Fは、行のセパレータを定義します。つまり、「ストール」します。セパレータの前のすべては$1でアドレス指定され、その後のすべては$2でアドレス指定されます。
  • /reg-ex/一致する正規表現、この場合は「ストール」を検索します。
  • {print $<n>}-n列を印刷します。セパレーターは停止したものとして定義されているため、停止した後のすべてが2番目の列と見なされます。
3
robertm.tum

より簡単な方法があるようです。ただ:

sed "s/installed.*//g"

"installed"の後のすべての単語を削除します。

for i in *
do
    se=$(echo $i|sed "s/---.*//g")
    echo $se
    mv "$i" $se
done
0
minor hash