awkコマンドを使用してこれら2つの出力を分離するにはどうすればよいですか

awkコマンドを使用してこれら2つの出力を分離するにはどうすればよいですか

これが私の出力です:

MessageID=3990592283244651750-30192b51.13df831d93a.7eb4;EsbTiming=2013-04-12T01:07:46.099

欲しいのは時間だけです。

どうすれば分離できるでしょうか?

答え1

入力の構造を分析します。

key1=value1;key2=value2

これらは で区切られたフィールドで、フィールド区切り記号;を作成することで解析できます。次に、フィールドの値を抽出するには、関数を使用して 部分を削除します(またはで2 番目の部分を取得するか、の の後の部分文字列を取得します)。時刻が常に 2 番目のフィールドにある場合は、次の方法が簡単です。;subkey=split/=/index=

awk -F ';' '{sub(/^[^=]*=/, $2); print $2}'

名前でフィールドにアクセスする場合 (おそらくより堅牢です)、フィールドをループすることができます。

awk -F ';' '{i=1; while (i <= NF) {if ($i ~ /^EsbTiming=/) {sub(/^[^=]*=/, $i); print $i}}}'

;解析する行が 1 行だけの場合は、レコード区切り文字と=フィールド区切り文字を作成する方が簡単です。

awk -F '=' -v RS=';' '$1 == "EsbTiming" {print $2}'

このコマンドは余分な改行を出力することに注意してください。シェル スクリプトのコマンド置換でこのコマンドを使用している場合は、これは問題になりません。この余分な改行が必要ない場合は、 (出力レコード区切り文字) を空の文字列に(… | awk …)設定します。ORS

awk -F '=' -v RS=';' -v ORS= '$1 == "EsbTiming" {print $2}'

直接的な正規表現アプローチもあり、ここでは良い結果が得られます。

awk 'match($0, /(^|;)EsbTiming=/) {s = substr($0, RSTART+RLENGTH); sub(/;.*/, "", s); print s}'

答え2

awk の回答はいくつかありますが、ここでは bash で実行できる方法の 1 つを示します。まず、変数の設定を評価します。

source <(echo "MessageID=3990592283244651750-30192b51.13df831d93a.7eb4;EsbTiming=2013-04-12T01:07:46.099")

直接アクセスできるようになりましたEsbTiming。例:

printf "Date: %s\nTime: %s\n" ${EsbTiming%T*} ${EsbTiming#*T}

出力:

Date: 2013-04-12
Time: 01:07:46.099

答え3

awk 'BEGIN{ FS=":" } /Timing/ {print $2":"$3 }' Input_file

または

awk  '/Timing/{split($0,arr,":") } {print arr[2]":"arr[3]}'  input_file

または

awk -F: '/Timing/{$1=""; print}'  input_file

Grepソリューション

grep -oP '(?<=EsbTiming=.{14}).*' Input_file

答え4

使用しても構わないのであればawksed非常に簡単な方法があります:

sed 's/.*Timing=//' file.txt |awk -FT '{print $2}'

sedこの部分は、文字列「Timing=」までのすべてを折りたたみ、次のようになります。

2013-04-12T01:07:46.099

awk文字「T」で分割し、時間を表す 2 番目のフィールドを出力します。

01:07:46.099

関連情報