0

私はこの質問を読んでいました 複数のパターンを選択するためのAwkコード

ユーザーはこれを入力として持っています

------------------------------------------------------------------------
r4544 | n479826 | 2012-08-28 07:12:33 -0400 (Tue, 28 Aug 2012) | 1 line
Changed paths:
   M /branches/8.6.0/conf/src/main/config/RTSConfig.xml

CET-402: some text comment
------------------------------------------------------------------------
r4550 | n479826 | 2012-09-04 05:51:29 -0400 (Tue, 04 Sep 2012) | 1 line
Changed paths:
   M /branches/8.6.0/conf/src/main/config/RTSConfig.xml
   M /branches/8.6.0/conf/src/main/config/base.cfg
   M /branches/8.6.0/conf/src/main/config/prod.cfg
   M /branches/8.6.0/conf/src/main/config/qa.cfg
   M /branches/8.6.0/conf/src/main/config/uat.cfg

CET-438: some text comment

そして彼はこれを出力として望んでいます

r4544 | n479826 | 2012-08-28 07:12:33 | /branches/8.6.0/conf/src/main/config/RTSConfig.xml
r4550 | n479826 | 2012-09-04 05:51:29 | /branches/8.6.0/conf/src/main/config/RTSConfig.xml
r4550 | n479826 | 2012-09-04 05:51:29 | /branches/8.6.0/conf/src/main/config/base.cfg
r4550 | n479826 | 2012-09-04 05:51:29 | /branches/8.6.0/conf/src/main/config/prod.cfg
r4550 | n479826 | 2012-09-04 05:51:29 | /branches/8.6.0/conf/src/main/config/qa.cfg
r4550 | n479826 | 2012-09-04 05:51:29 | /branches/8.6.0/conf/src/main/config/uat.cfg

正解はこれ

awk -F"|" '/^r/{a=$1;b=$2;c=substr($3,0,20)}/^   M/{gsub(/   M /," ");print a"|"b"|"c"|"$0}' your_file

私はそれを完全には理解していませんでした。

今、私はこの部分を手に入れました

/^r/{a=$1;b=$2;c=substr($3,0,20)}/^

しかし、私は第二部を取得しませんでした M/{gsub(/ M /," ");print a"|"b"|"c"|"$0}

私の問題は

  1. M最初の意味 2.awk はファイルを 1 行ずつ読み取るため、2 行目、つまり Chngaed パスの値を意味します。その行a =0にはフィールドセパレーターがないためです。|
  2. awk が 3 行目に来ると、再びa,b,c =0結果$0 = /bracnhesに a、b、c の古い値が表示されます。

複数行で awk を使用すると混乱する

4

3 に答える 3

1

私は答えを説明するのに十分怠惰でした:)しかし、レムは私の怠惰をしばらく脇に置きました:

/^r/{a=$1;b=$2;c=substr($3,0,20)}

上記のコード ブロックは、行が文字 r で始まる場合にのみ実行されます。ブロック内では、最初のフィールドを a に保存し、2 番目のフィールドを b に保存し、3 番目のフィールドを入力から次のように保存します。

2012-08-28 07:12:33 -0400 (Tue, 28 Aug 2012)

しかし、タイムスタンプ付きの日付だけが必要で、残りは時代遅れです。常に 20 文字です。そのため、3 番目のフィールドから部分文字列を取得し、c に格納しました。

私の主な関心は /^ M/ で始まる行でした。これは、r で始まる前の行に存在する情報とともに表示する必要があり、確かに、すべての情報を含む目的の行の前に r で始まる行があります。 M で始まる行を先頭に追加する必要があります。

そのため、行が M で始まるたびに、ab と c に格納されている値が先頭に追加されます。

M/{gsub(/ M /," ");print a"|"b"|"c"|"$0}

gsub part は、現在の行からスペースを含む " M " の部分を削除します。印刷部分は、ab と c の値を現在の行に | で追加するだけです。セパレータとして。

これがロジックです!

私は今、怠惰なモードに戻ります:)

于 2013-01-16T07:11:16.200 に答える
1

このようにしてください

/^r/{a=$1;b=$2;c=substr($3,0,20)}

  1. rと数字で始まる行のみに一致します。a、b、c変数を取得します

/^ M/{gsub(/ M /," ");print a"|"b"|"c"|"$0}

  1. spaces and Mこれは、他の部分を取得するために で始まる行に一致します。このマッチング中に、a、b、c は以前に保存された値から取得されます。
于 2013-01-16T06:51:40.480 に答える
0

これは、a、b、および c の値が M に遭遇する前に置き換えられないためです。そのため、引き続き print ステートメントに追加されます。

于 2013-01-16T10:11:32.570 に答える