ファイルがあります。内容は次のとおりです。
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
。次に、それぞれの正規表現に一致する最初の行^}
(たとえば、で始まる}
)を探します。ジェイverify
oinsと}
(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
印刷してから消去します。 - 空白行を印刷します。