sed はインラインコメントを削除します。

sed はインラインコメントを削除します。

jsファイルからコメントを削除する単純なbashスクリプトがあります。

#!/bin/bash
sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' $1 >> stripped.js

インラインコメントを除くとほぼ完璧です。

// file-to-be-stripped.js
...
...
const someVar = 'var' // this comment won't be stripped
// this comment will be stripped

インラインコメントを削除するには何がありましたか?

修正する:

本当に奇妙なことは、オンラインbashシェルを使って例を始めましたが、完全に実行されたことです!しかし、まったく同じコードをローカルで実行しても、インラインコードは削除されません! ?なぜ/どのようにこれが起こるのかご存知ですか?私は明らかに何かを見逃しています...非常に奇妙です。

更新されたコードは次のとおりです。

私のスクリプト:Stripper.sh

#!/bin/bash
sed -E -e 's:(\s+(//|#)|^\s*(//|#)).*$::; /^$/d' $1 > "stripped.${1}"

私のテストファイル:test.js

// testies one
const testies = 'two'
console.log(testies) // three
// testies FOUR!?
console.log('Mmmmm toast') // I won't be stripped of my rights!

次に実行します。./stripper.sh test.js出力は次のとおりです。

const testies = 'two'
console.log(testies) // three
console.log('Mmmmm toast') // I won't be stripped of my rights!

まったく同じコードがローカルで実行されますが、sedの行全体が次のようにコメントアウトされる理由についてのアイデアがあります。オンラインbash通訳(残念ながら、私のシェルへの正確なリンクはbit.lyリンクなので共有できません。ここでは明らかに「いいえ」です。)これは期待どおりに機能しますか?

答え1

POSIXlyでは、次のようにします。

sed '
  s|[[:blank:]]*//.*||; # remove //comments
  s|[[:blank:]]*#.*||; # remove #comments
  t prune
  b
  :prune
  /./!d; # remove empty lines, but only those that
         # become empty as a result of comment stripping'

GNUを使用すると、sed次のように短縮できます。

sed -E 's@[[:blank:]]*(//|#).*@@;T;/./!d'

#thingsこれは喜んで削除され、//things次のコメントではないことに注意してください。

const url = 'http://stackexchange.com';
x = "foo#bar";

内部引用符を無視#するには//、次のようにします。

perl -ne 'if (/./) {
   s{\s*(?://|#).*|("(?:\\.|[^"])*"|'"'(?:\\\\.|[^'])*'"'|.)}{$1}g;
   print if /./} else {print}'

次のように入力すると:

#blah
// testies one
const testies = 'two';
console.log(testies) // three

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar" # comment
y = 'foo\'bar' # it's a comment

それは以下を提供します:

const testies = 'two';
console.log(testies)

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar"
y = 'foo\'bar'

#(このファイルの実際の言語に適応する必要があるかもしれません。node.jsで始まる最初の行を除いて、JavaScriptがコメントをサポートしているかどうかわかりません#!。)

答え2

sed -e '/^\/\//d' -e 's@\(.*\)[[:blank:]]\{1,\}//.*@\1@' your_file

この sed コマンドは、コメントで始まる行を削除し、インラインコメントの場合、コメントから行の終わりまでコードを区切るスペースの内容をすべて削除します。 POSIX(GNU拡張を使用しない)であり、OPの元の例と読みやすさに基づいて、このバージョンはコメントのみをサポートしています//(詳細は以下を参照)。

詳細

このsed呼び出しには、「パターン一致時の削除」と置換の2つのsedコマンドが含まれています。

前者はです/^\/\//d。このパターンは、^\/\/2 つのスラッシュ (たとえば "//foo bar") で始まる行と一致します。この行は削除され、次の行がすぐに導入されます(つまり、置き換えはスキップされます)。

交換するパターンはです\(.*\)[[:blank:]]\{1,\}//.*。注:区切り文字に必要な文字のエスケープを@防ぐために区切り文字として使用しています。/

  • \(.. \)- 一致するすべての項目を逆参照として使用できます。
  • .*- 代替部分のゼロ個以上の文字(改行文字を除くすべての文字)と一致します。\(周囲の合計のおかげで、ここで一致するすべての文字を参照できます\)
  • [[:blank:]]- 空白文字
  • \{1,\}- 前の1つ以上の項目と一致します([[:blank:]]この場合)。
  • //- 2つのスラッシュと一致します(つまり、コメントの先頭)。
  • .*- 上記と同じですが、逆参照で使用できない

交換部分は、\1最初の逆参照、つまり.*前の逆参照と一致する項目を置き換えることを意味します[[:blank:]]

したがって、私が説明したように動作します。インラインコメントの場合は、コメントと行の最後までコードを区切る空白のすべての項目を削除します。

「#」コメント

GNU sedハンドルを使用してコメントを追加すると、代替アイテムに#置き換え//られます(#|//)(または必要に応じてエスケープされます\(#\|\/\/\))。ただし、POSIX方式でこれを行うことは、代替がサポートされていないため、はるかに冗長です。明らかに、既存のsedコマンドを繰り返してこれを行うことができます#。より良いことは、よりきれいなアプローチを示す答えが投稿されているということです。とにかく、ここでは解決策を繰り返しません。

編集する:

私は長い間これを再び訪問し、私は交換が必要なものよりも複雑であることに気づき、コメントで指摘したように(例えば、「something // foo // bar」..only「//bar」は削除)。

私はこれが私たちに必要なものだと思います...

sed -e '/^\/\//d' -e 's@[[:blank:]]\{1,\}//.*@@' your_file

つまり、置換部分は、「最初のスペース - スラッシュ - スラッシュが発生したときに前のテキストを保持しながら、そのエントリとその後のすべてのエントリを削除します」を意味します。

答え3

これを使用して、スタイルコメントだけでなくスタイルコメントをGNU sedフィルタリングする小さなパーサーコードを書くこともできます。C++//sh#

構造をモジュール化して拡張可能にするために、シェル変数で定義され、適切に参照される固定正規表現を使用します。

このコードをsed使用すると、空行を渡すことができます。次に、行でバランスのとれない二重引用符を見つけます。バランスがとれるまで次の行を引き続けます。これは、引用符が複数行にあふれるようにするためです。

一重引用符も同様です。

次に、末尾のバックスラッシュで識別される連続した行を見つけます。

最後に、引用された単語やコメントではなく単純な単語をスキップし続けます。

この変換後に何も残らない場合は、それを削除し、OTWはすぐにdecommentifiedその行を標準出力に印刷します。

bashPS:二重引用符内の文字を抑制できないコマンドラインのエラーを解決するために、sed -e ...で一重引用符と二重引用符を混合して一重引用符!で囲みました。

# symbol names
q=\' Q=\"
d=\$ b=\\
B=$b$b

# construct regexes using symbolic names
single_quotes_open="$q[^$b$q]*($B.[^$b$q]*)*$d"
single_quoted_word="$q[^$b$q]*($B.[^$b$q]*)*$q"
double_quoted_word="$Q[^$b$Q]*($B.[^$b$Q]*)*$Q"
double_quotes_open="$Q[^$b$Q]*($B.[^$b$Q]*)*$d"
quoted_word="$double_quoted_word|$single_quoted_word"

# decomment a c++ file
sed -Ee '
   /\S/!b'"
   :a;/(^|\s)$double_quotes_open/{N;ba;}
   :b;/(^|\s)$single_quotes_open/{N;bb;}
   :c;/$B$d/{N;bc;}
   s_\s*(//|#).*|($quoted_word|.)_\2_g
   "'/\S/!d
' c_file

答え4

ソースファイルからコメントを削除するには、私のcomcatツールを試してください。最新1泊版利用可能GitHubから

  • コメントのみを表示するか、コメントを除くすべてのアイテムを表示できます。
  • これは非常に初期のプロジェクトなので、いくつかのバグが予想されます。

私はこれが質問であることを知っていますsed。この答えが役に立たないと思われる場合は、削除してください。

婦人声明:私はcomcatの管理者です。

関連情報