複数のsedコマンドがあります。関連情報の抽出
私のファイルSample.log(ncsa.log形式)は次のとおりです。
2012_04_01_filename.log:29874:192.168.1.12 - - [16/Aug/2012:12:54:21 +0000] "GET /cxf/myservice01/v1/abc?anyparam=anything&anotherone=another HTTP/1.1" 200 3224 "-" "client name"
2012_04_01_filename.log:29874:192.168.1.12 - - [16/Aug/2012:12:54:25 +0000] "GET /cxf/myservice02/v1/XYZ?anyparam=anything&anotherone=another HTTP/1.1" 200 3224 "-" "client name"
2012_04_01_filename.log:29874:192.168.1.12 - - [16/Aug/2012:12:56:52 +0000] "GET /cxf/myservice01/v1/rsv/USER02?anyparam=anything&anotherone=another HTTP/1.1" 200 6456 "-" "client name"
2012_04_01_filename.log:29874:192.168.1.12 - - [16/Aug/2012:12:58:52 +0000] "GET /cxf/myservice01/v2/upr/USER01?anyparam=anything&anotherone=another HTTP/1.1" 200 2424 "-" "client name"
2012_04_01_filename.log:29874:192.168.1.12 - - [16/Aug/2012:12:59:11 +0000] "GET /cxf/myservice02/v1/xyz?anyparam=anything&anotherone=another HTTP/1.1" 200 233 "-" "client name"
このパイプで接続された sed セットは、必要な URL の詳細を抽出します (最初の sed: \1 = YYYY-MM-DD 日付、 \2 = service0x、 \3 = トライグラム、 \4 = オプションのエンティティ ID、\5 = HTTPレスポンスコード、\ 6 = httpレスポンスサイズ)
more sample.log | sed -r 's#^(...._.._..)_.*/cxf/(myservice.*)/v./(.{3})[/]*([a-Z0-9]*)?.*\sHTTP/1.1.\s(.{3})\s([0-9]*)\s.*#\1;\2;\L\3;\E\4;\5;\6#g' | sed -r 's!(.*;.*;.{3};)[a-Z0-9]+(;.*;.*)!\1retrieve\2!g' | sed -r 's!(.*);;(.*)!\1;list;\2!g' > request-by-operation.txt
必要な結果は次のとおりです。
2012_04_01;myservice01;abc;list;200;3224
2012_04_01;myservice02;xyz;list;200;3224
2012_04_01;myservice01;rsv;retrieve;200;6456
2012_04_01;myservice01;upr;retrieve;200;2424
2012_04_01;myservice02;xyz;list;200;233
list
2つの異なるsedパイプ(タスクを実行する)を使用する以外に、andタスクを変換する他の方法が見つかりませんでした。retrieve
sedはセクション(特定のグループの場合)でコマンドの置き換えをサポートしていないと聞きましたが、1#\1;\2;\L\3;\Eifnull(\4, "list", "retrieve");\5;\6#
つのsedコマンドを使用して別の方法で実行できるかどうか疑問に思いました。
答え1
sed
交換セクションのコマンドは呼び出すことはできませんが、複数の交換を実行できます。この場合、すべての代替項目を1つにまとめるとうまくいくsed
ようです。
sed -r 's#^(...._.._..)_.*/cxf/(myservice.*)/v./(.{3})[/]*([a-Z0-9]*)?.*\sHTTP/1.1.\s(.{3})\s([0-9]*)\s.*#\1;\2;\L\3;\E\4;\5;\6#g;
s!(.*;.*;.{3};)[a-Z0-9]+(;.*;.*)!\1retrieve\2!g;
s!(.*);;(.*)!\1;list;\2!g'
答え2
必要な部分を選択できますが、不要な部分を削除することもできます。
sed '
s|_[^_]* /[^/]*/|;|
s|/[^/]*/\(...\)|;\L\1|
s|?[^"]*" |;list;|
s|/.*;|;retrieve;|
s/ /;/
s/ .*$//'
答え3
GNU sedにはコマンドがありますが、s///e
以下を送信します。みんな評価のためにシェルのパターンスペース:
$ echo "echo hello world" | sed 's/world/foo bar | rev/e'
rab oof olleh
したがって、「world」は「foo bar | rev」に置き換えられます。パターン空間は「echo hello foo bar | rev」です。これはシェルに転送され、出力はパターン空間に配置され、暗黙的に印刷されます。
Perlのe
フラグを使用すると、文字列の一致する部分にのみ集中できます。
バラよりhttps://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-command
金利
このコマンドを使用すると、シェルコマンドの入力をパターンスペースにパイプできます。置換が行われると、パターン空間内のコマンドが実行され、その出力がパターン空間を置き換えます。末尾の改行は抑制されます。実行するコマンドにヌル文字が含まれている場合、結果は定義されません。これはGNU sed拡張です。