スクリプトの代わりにSEDコマンドを使用するソリューション

スクリプトの代わりにSEDコマンドを使用するソリューション

試しましたが、sed関連文字がすでにコマンドに区切り文字として含まれているawkため、機能しません。/

これを達成する方法を教えてください。

ここに例があります。私たちはコメント部分を削除したいと思います。/*.....*/

/*This is to print the output
data*/
proc print data=sashelp.cars;
run;
/*Creating dataset*/
data abc;
set xyz;
run;

答え1

簡単な解決策を見つけたと思います!

cpp -P yourcommentedfile.txt 

いくつかのアップデート:

ユーザーの引用イルカチョ(ネチズンコメントの原文):

私はgccオプションで遊んだ。-f 前処理ほとんどのディレクティブとマクロ拡張は無効になります(#defineと#undefは除く)。次へ追加-dD定義も残ります。標準=c89// 新しいスタイルのコメントを無視するために使用できます。存在していても、cppはコメントを空白に置き換え(削除するのではなく)、空白と空白行を縮小します。

しかし、これはほとんどの場合まだ合理的で簡単な解決策であると考えています。マクロの拡張やその他の機能を無効にすると良い結果が得られると思います。 ..そしてもっと...

答え2

一度調べました。これこれを次のように細分化できます。

perl -0777 -pe '
  s{
    # /* ... */ C comments
    / (?<lc> # line continuation
        (?<bs> # backslash in its regular or trigraph form
          \\ | \?\?/
        )
        (?: \n | \r\n?) # handling LF, CR and CRLF line delimiters
      )* \* .*? \* (?&lc)* /
    | / (?&lc)* / (?:(?&lc) | [^\r\n])* # // C++/C99 comments
    | (?<code> # tokenising anything else
         "(?:(?&bs)(?&lc)*.|.)*?" # "strings" literals
       | '\''(?&lc)*(?:(?&bs)(?&lc)*(?:\?\?.|.))?(?:\?\?.|.)*?'\'' # (w)char literals
       | \?\?'\'' # trigraph form of ^
       | .[^'\''"/?]* # anything else
      )
  }{$+{code} eq "" ? " " : $+{code}}exsg'

より多くのコーナーケースを処理します。

あなたが削除するコメント、コードの意味を変更することができます(1-/* comment */-1while(コメントを削除すると取得できます)などの解析ではエラーが発生します)。コメントを完全に削除するよりも(ここでやったように)空白文字に置き換える方が良いです。1 - -11--1

上記のコードは、この有効なANSI Cコードで正しく機能する必要があります。たとえば、次のような特殊なケースを含めてみてください。

#include <stdio.h>
整数メイン()
{
  printf("%d %s %c%c%c%c%c %s %s %d\n",
  1-/* 説明*/-1,
  /\
*コメント*/
  "/*コメントではない*/",
  /* 複数行
  コメント*/
  '"' /* コメント*/ , '"',
  '\'','"'/* コメント*/,
  '\
\
"'、/*コメント*/
  "\
" /* コメントではない */ ",
  "??/" /* コメントではない*/ ",
  '??''+'"' /* "コメント" */);
  0を返します。
}

これにより、次の出力が提供されます。

#include <stdio.h>
整数メイン()
{
  printf("%d %s %c%c%c%c%c %s %s %d\n",
  1--1、
   
  "/*コメントではない*/",
   
  ''', ''',
  '\'','"',
  '\
\
「」、  
  "\
" /* コメントではない */ ",
  "??/" /* コメントではない*/ ",
  '??''+'"');
  0を返します。
}

コンパイルして実行すると、両方とも同じ出力を印刷します。

の出力と比較して、gcc -ansi -Eプリプロセッサがどのような操作を実行しているかを確認できます。このコードは有効なC99またはC11コードでもありますが、3文字のサポートはデフォルトで無効になっているため、gcc基準を指定(オプションの追加など)しないと機能しません。gccgcc -std=c99gcc -std=c11-trigraphs

また、次のC99 / C11(非ANSI / C90)コードでも機能します。

//コメント
/\
/コメント
//複数行\
コメント
"//コメントではありません。"

gcc -E//と比較gcc -std=c99 -Egcc -std=c11 -E

ANSI Cはコメントをサポートしていません// form//ANSI Cでは効果がないのでそこには現れません。 ANSI Cで実際に発生する可能性のある人工的なケース//(前述のように)そこ、残りの議論は興味深いかもしれません。)文字列化演算子を使用しています。

これは有効なANSI Cコードです。

#define s(x) #x
s(//not a comment)

そして2004年に議論されたときにgcc -ansi -E実際に拡張されました"//not a comment"。しかし、現在はgcc-5.4エラーが返されるので、この構成を使用するCコードがたくさん見つかるかどうか疑問です。

GNUにsed対応する内容は次のとおりです。

lc='([\\%]\n|[\\%]\r\n?)'
sed -zE "
  s/_/_u/g;s/!/_b/g;s/</_l/g;s/>/_r/g;s/:/_c/g;s/;/_s/g;s/@/_a/g;s/%/_p/g;
  s@\?\?/@%@g;s@/$lc*\*@:&@g;s@\*$lc*/@;&@g
  s:/$lc*/:@&:g;s/\?\?'/!/g
  s#:/$lc*\*[^;]*;\*$lc*/|@/$lc*/([\\\\%].|[^\\\\%\n\r])*|(\"($lc|[\\\\%]$lc*[^\r\n]|[^\\\\%\"])*\"|'$lc*([\\\\%]$lc*[^\r\n])?([^\\\\%']|$lc)*'|$lc|[^'\"@;:]+)#<\5>#g
  s/<>/ /g;s/!/??'/g;s@%@??/@g;s/[<>@:;]//g
  s/_p/%/g;s/_a/@/g;s/_s/;/g;s/_c/:/g;s/_r/>/g;s/_l/</g;s/_b/!/g;s/_u/_/g"

GNUが古すぎてorをsedサポートできない場合は、最初の行を次のように置き換えることができます。-E-z

sed -r ":1;\$!{N;b1}

答え3

そしてsed

修正する

/\/\*/ {
    /\*\// {
        s/\/\*.*\*\///g;
        b next
    };

    :loop;
    /\*\//! {
        N;
        b loop
    };
    /\*\// {
        s/\/\*.*\*\//\n/g
    }
    :next
}

すべての可能性をサポートします(複数行のコメント、[or and]の後のデータ)。

 e1/*comment*/
-------------------
e1/*comment*/e2
-------------------
/*comment*/e2
-------------------
e1/*com
ment*/
-------------------
e1/*com
ment*/e2
-------------------
/*com
ment*/e2
-------------------
e1/*com
1
2
ment*/
-------------------
e1/*com
1
2
ment*/e2
-------------------
/*com
1
2
ment*/e2
-------------------
ランニング:
$ sed -f command.sed FILENAME

e1
-------------------
e1e2
-------------------
e2
-------------------
e1

-------------------
e1
e2
-------------------

e2
-------------------
e1

-------------------
e1
e2
-------------------

e2
-------------------

答え4

スクリプトの代わりにSEDコマンドを使用するソリューション

あなたのため:

sed 's/\*\//\n&/g' test | sed '/\/\*/,/\*\//d'

気づくこれがインストールされていないと、OS Xでは機能しませんgnu-sed。しかし、Linuxディストリビューションでは動作します。

関連情報