行をマージする方法(複数行コードルーチンの場合)

行をマージする方法(複数行コードルーチンの場合)

ファイルがあります。内容は次のとおりです。

cat -n /tmp/my_file

 1  verify(abc) {
 2    foo : bar;
 3    sub1(aa) {
 4    line1;
 5    } 
 6    sub2 (bb) {
 7    line1;
 8    // this line is a comment and must be ignored
 9    line2;
10       sub3 (cc) {
11       line1;
12     }
13    }  
14  }
15  
16  verify(efg) {
17    foo : bar;
18    sub1(aa) {
19    line1;
20    } 
21    sub2 (bb) {
22    line1;
23    // this line is a comment and must be ignored
24    line2;
25       sub3 (cc) {
26       line1;
27     }
28    }  
29  }

(行番号は説明目的でのみ使用され、ファイルの一部ではありません。)

コンテンツを次の形式に変換するには、awkまたはPerlを使用する必要があります。

verify(abc) { foo : bar; sub1 (aa) { line1; } sub2 (bb) { line1; line2; sub3 (cc) { line1; } } }

verify(efg) { foo : bar; sub1 (aa) { line1; } sub2 (bb) { line1; line2; sub3 (cc) { line1; } } }

どうすればいいですか?

答え1

一行:

awk '{ if ( NF > 0 && $1 !~ /^\/\// ) { bl=0; for (i=1;i<=NF;i++) printf "%s ", $i }; ( NF == 0 && bl == 1 ) {printf "\n" }; if(NF == 0&&bl == 0){bl = 1; printf "\n\n" } } END { if ( bl == 0 ) { printf "\n" } } ' /tmp/my_file

説明する:

if ( NF > 0 && $1 !~ /^\/\// ) { bl=0; for (i=1;i<=NF;i++) printf "%s ", $i }

フィールド数がゼロより大きく、最初のフィールドがコメントでない場合は、そのフィールドと各フィールドのスペースを印刷します。正規表現は実際には「^//」(「//」で始まります)ですが、「/」はエスケープする必要があるため「\/」になります。また、bl = 0は前の空行フラグを設定します。このフラグは、後でステートメント内のレコードの終わり/空行ハンドルを制御するために使用されます。

次に、空白行/レコード終了状況を処理します。

まず、これが空行であることを確認してください。

if ( NF == 0 && bl == 1 ) {printf "\n" };

フィールド数が0で、前の空行フラグが設定されている場合は、改行文字のみが印刷されます。

次に、データ/テキスト行を終了し、別の行を追加する必要があるかどうかをテストします。

if ( NF == 0 && bl == 0 ) {bl=1 printf "\n\n" }

フィールド数が 0 で前の空行フラグが設定されていない場合は、空行フラグが設定され、行の終わりが印刷されます。

ついに! ! !

END { if ( bl == 0 ) { printf "\n" } }

ファイルが完成したら、レコード行終端が印刷されることを確認し、それ以外の場合は印刷します。

答え2

各ブロック(各 "verify()"ルーチン)は1行で始まりverify 、1行で終わります} (そして行がないと仮定します)。以内にルーチンは})で始まり、すべてのスペースは空白です。

前任者

printf '%s\n' 'g|^ *//|d' 'g/^verify/.,/^}/j' x | ex -- /tmp/my_file

ex(コマンドラインバージョン/)を使ってvi ファイルを編集しますvim

  • g|^ *//|d正規表現に一致するすべての行を見つけて^ *// (つまり、//0個以上のスペースを含み、それ以外は何も含まない)削除します。
  • g/^verify/.,/^}/j正規表現に一致する^verify(つまり、で始まる)すべての行を見つけますverify。次に、それぞれの正規表現に一致する最初の行^} (たとえば、で始まる  })を探します。ジェイverifyoinsと}(inclusive)の間のすべての行で絞り込まれた改行文字の前後の余分なスペースは削除されます。
  • x保存と終了。
    メモ:入力ファイルが上書きされます。

sed

sed -n '/^verify/ { h; d }; /^ *\/\//d; /./H; /^}/ { g; s/ *\n */ /gp }; /^$/p' /tmp/my_file
  • -n- 指示がない限り印刷しないでください。
  • /^verify/ { h; d }— で始まる行が表示されたら、verify次の場所にコピーします。時間古い空間とDパターンスペースを削除します(つまり、追加の処理なしで次の入力行に進みます)。
  • /^ *\/\//d— ゼロ個以上のスペースで始まる行の合計が表示されたら、//削除します(つまり、追加の処理なしで次の入力行に進みます)。
  • /./H- 上記以外の空ではない行を予約済みスペースに追加します。
  • /^}/ { g; s/ *\n */ /gp }}— 次に始まる行を見るときG保持スペースをパターンスペースとして設定します。次に、埋め込まれた各改行文字(および前と次のスペース)を単一のスペースに置き換えて単一の行に圧縮して印刷します。
  • /^$/p- 空白行を印刷します。

アッ

awk '
    /^ *\/\//   { next; }
    /./         { buffer = buffer " " $0; }
    /^}/        { sub(/^ */, "", buffer); sub(/ *$/, "", buffer);
                  gsub(/ * /, " ", buffer); print buffer; buffer = ""; }
    /^$/        { print; }
    ' /tmp/my_file
  • コメントを見たらスキップしてください。
  • 空でない他のすべての行をに接続しますbuffer。改行は暗黙的に削除されます。
  • で始まる行が表示されたら、}その中の余分なスペースをすべて削除してbuffer印刷してから消去します。
  • 空白行を印刷します。

関連情報