sedに置換部分(正規表現グループ)でいくつかのロジックを実行させることはできますか?

sedに置換部分(正規表現グループ)でいくつかのロジックを実行させることはできますか?

複数の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

list2つの異なる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拡張です。

関連情報