2

sed と s/regex/../ の組み合わせをいくつか試しましたが、成功しませんでした。だからここに私の質問があります:私はこのようなテキストファイルを持っています(PCLint出力)

--- Module A
    Info: indented message 1
    Note: indented message 2
    Warning: indented message 3
--- Module B
--- Module C
    Info: indented message 1
--- Module D

結果を次のようなものに変更したい (teamcity サービス メッセージ):

[Start Module="Module A"]
    [Message Content="Info: indented message 1"]
    [Message Content="Note: indented message 2"]
    [Message Content="Warning: indented message 3"]
[End Module="Module A"]
[Start Module="Module B"]
[End Module="Module B"]
[Start Module="Module C"]
    [Message Content="Info: indented message 1"]
[End Module="Module C"]
[Start Module="Module D"]
[End Module="Module D"]

したがって、テキストは「---」ごとに何らかの形でブロックに分割されることを知っています。次に、テキストブロックを正規表現の力でラップ/置換する必要があります。しかし、これを効率的に行う方法がわかりません。理想的には、ツールを「シンプル」に保つために、busybox で利用可能なツール (sed、awk など) を使用するのが好きです (Win64 で作業する必要があります)。

正規表現はうまく機能しますが、これをスコープすることはできませんでした。そこに私のためのヒントはありますか?

4

3 に答える 3

4

オークはこれを行うことができます。/^---/どのモジュールにいるかを記録する変数を設定し、前のモジュール (存在する場合) の End 行と次のモジュールの Start 行を出力する、一致する 1 つの句が必要です。次に、メッセージ行を出力する 2 番目の節です。

$ cat input | awk '/^---/ { IFS=" "; oldM=M; M=$3; if (oldM) { print "[End Module=\"Module " oldM "\"]"; }; print "[Begin Module=\"Module " M "\"]"; } /^    (.*)$/ { gsub(/^ +/, "", $0); print "    [Message Content=\"" $0 "\"]"; } END { print "[End Module=\"Module " M "\"]"; }'
[Begin Module="Module A"]
    [Message Content="Info: indented message 1"]
    [Message Content="Note: indented message 2"]
    [Message Content="Warning: indented message 3"]
[End Module="Module A"]
[Begin Module="Module B"]
[End Module="Module B"]
[Begin Module="Module C"]
    [Message Content="Info: indented message 1"]
[End Module="Module C"]
[Begin Module="Module D"]
[End Module="Module D"]
于 2015-05-20T19:48:41.743 に答える
1

sedそのためのスクリプトを次に示します。

翻訳.sed:

:a
/Module/ {
    x
    s/.*Module (.*)/[End Module="\1"]/p
    x
    h
    s/(--- )(.*)/[Start Module="\2"]/p
    :b
    n
    /Module/! {
        s/(\s*)(.*)/\1[Message Content="\2"]/p
        bb
    }
    /Module/ {
        $!ba
        h
        s/(--- )(.*)/[Start Module="\2"]/p
        x
        s/.*Module (.*)/[End Module="\1"]/p
    }
}

次のように実行します。

sed -nrf translate.sed file.txt

出力:

[Start Module="Module A"]
    [Message Content="Info: indented message 1"]
    [Message Content="Note: indented message 2"]
    [Message Content="Warning: indented message 3"]
[End Module="A"]
[Start Module="Module B"]
[End Module="B"]
[Start Module="Module C"]
    [Message Content="Info: indented message 1"]
[End Module="C"]
[Start Module="Module D"]

説明が追加された同じバージョンのスクリプトを次に示します。

翻訳.sed

# Define lable 'a' to iterate over modules
:a

# If the line module is matched ...
/Module/ {
    # Swap contents of hold and pattern buffer (current line)
    x

    # If the pattern buffer (former hold buffer)
    # contains something it is a module starting line.
    # Create and end tag out of it.
    s/.*Module (.*)/[End Module="\1"]/p

    # Get the current line back from hold buffer
    x

    h

    # Create a start module tag
    s/(--- )(.*)/[Start Module="\2"]/p

    # Create a label to iterate over messages
    :b

    # Get next line from input into pattern buffer
    # (Overwrite the pattern buffer)
    n

    # If it is not a module starting line ...
    /Module/! {

        # ... wrap it into the Message Content tag
        s/(\s*)(.*)/\1[Message Content="\2"]/p

        # and go on with the next line (step back to b)     
        bb
    }

    /Module/ {
        # if it is not the last line 
        # go on with the next module (step back to a)
        $!ba

        # on the last line ...

        # backup the current line in the hold buffer
        h

        # create start tag
        s/(--- )(.*)/[Start Module="\2"]/p

        # swap hold and pattern buffer
        x

        # create the end tag
        s/.*Module (.*)/[End Module="\1"]/p
    }
}

ところで、もちろんワンライナーにすることもできます:D

sed -rn ':a;/Module/{;x;s/.*Module(.*)/[EndModule="\1"]/p;x;h;s/(---)(.*)/[StartModule="\2"]/p;:b;n;/Module/!{;s/(\s*)(.*)/\1[MessageContent="\2"]/p;;bb;};/Module/{;$!ba;h;s/(---)(.*)/[StartModule="\2"]/p;x;s/.*Module(.*)/[EndModule="\1"]/p;};};' file.txt
于 2015-05-20T20:15:19.083 に答える
0
sed '# prepare loading
   s/^--- Module \(.*\)/[Start Module="\1"]\
[End Module="\1"]/
   s/^\([[:space:]]\{4\}\)\(.*\)/\1[Message Content="\2"]/
   H;$!d

# permutation
   x;s/\n/²/g;s/$/²/
:cycle
   s/²\(\[End[^²]*\)²\([[:space:]][^²]*\)²/²\2²\1/g
   t cycle
   s/.//;s/.$//;s/²/\
/g
' YourFile

recursif 変更を使用する

  • メッセージ行を変更
  • メモリー内の行を読み込み、サイクル読み取り ( では出力なしd)
  • 最後に memoy コンテンツを読み込みます
  • 改行を他の文字で置き換える ( [^\n]posix バージョンでは許可されていません)
  • 必要に応じて、モジュールの末尾をメッセージの内容で置き換えます
  • 新しい行を再表示します(余分な行を削除します)
  • 出力結果

通常、GNU sed では改行の置換は必要ないため、コード内で直接変更²し、置換部分を削除します\n

于 2015-05-21T09:07:45.713 に答える