エスケープされたハッシュ文字を含むファイルからすべてのコメントを削除する方法

エスケープされたハッシュ文字を含むファイルからすべてのコメントを削除する方法

この質問は以前に要求されたことがあることを知っていますが、これは少し異なります。エスケープされたコメント#または開始コメントを意味しないコメント(単一または二重頂点の間)を除くすべてのコメントを削除する必要があります。

次のテキストで始めてください。

test
# comment
comment on midline # comment
escaped hash "\# this is an escaped hash"
escaped hash "\\# this is not a comment"
not a comment "# this is not a comment - double apices"
not a comment '# this is not a comment - single apices'
this is a comment \\# this is a comment
this is not a comment \# this is not a comment

欲しい

test
comment on midline
escaped hash "\# this is an escaped hash"
escaped hash "\\# this is not a comment"
not a comment "# this is not a comment - double apices"
not a comment '# this is not a comment - single apices'
this is a comment \\
this is not a comment \# this is not a comment

頑張った

grep -o '^[^#]*' file

ただし、これによりエスケープされたハッシュも削除されます。

注:私が扱っているテキストは実際にエスケープ#\#)されていますが、二重エスケープ#\\#)が不足しているので、保存するかどうかは重要ではありません。ハッシュがエスケープされないという事実のため、削除する方がよりきれいになると思います。

答え1

a(ゼロ以上の空白が前にある)sedで始まる行を削除し、その後に単一のバックスラッシュがない(引用符1の間にない場合にのみ)、それで始まるすべての文字列を削除できます。##

sed '/^[[:blank:]]*#/d
/["'\''].*#.*["'\'']/!{
s/\\\\#.*/\\\\/
s/\([^\]\)#.*/\1/
}' infile

1:この解決策は一行に引用符のペアがあると仮定します。

答え2

これはビューよりも複雑な問題ですが、正規表現の機能を超えているわけではありません。分析してみてください。行全体はコメントではなくテキストで構成され、オプションでコメントテキストが続きます。コメント以外のテキストに表示される内容:

  1. , \, #,'を除くすべての文字"
  2. \その後にランダムな文字が続きます。
  3. andで始まり終わる引用符付き文字列"(次を含めることができます)
    • \a) を除くすべての文字"
    • B)の\後ろに任意の文字が続きます。
  4. andで始まり終わる引用符付き文字列'(次を含めることができます)
    • 削除する'

(両方の参照はUnixシェルの処理方法によって異なります。お好みに合わせて調整してください。)

これを正規表現に直接変換するには、次のものが必要です。

s/^([non comment])[comment]$/\1/
non comment = ([^\\"'#]|\\.|"([^\\"]|\\.)*"|'[^']*')*
              (11111111|222|3(AAAAAA|BBB)33|4444444)*
comment = #.*
Therefore
s/^(([^\\"'#]|\\.|"([^\\"]|\\.)*"|'[^']*')*)#.*$/\1/

sed正規表現の場合と文字の前にバックスラッシュを追加する必要があります。(|)

s/^\(\([^\\"'#]\|\\.\|"\([^\\"]\|\\.\)*"\|'[^']*'\)*\)#.*$/\1/

Bashには追加の引用符が必要です。

sed 's/^\(\([^\\"'\''#]\|\\.\|"\([^\\"]\|\\.\)*"\|'\''[^'\'']*'\''\)*\)#.*$/\1/'

grep -o編集:@StéphaneChazelasの答えを見るまで、これが存在することを知りませんでした。同じコア正規表現をこのアプローチに適用できます。egrepを使用すると、余分なバックスラッシュをほとんど実行する必要がなくなります。

grep -Eo '^([^\\"'\''#]|\\.|"([^\\"]|\\.)*"|'\''[^'\'']*'\'')*'
grep -Eo "^([^\\\\\"'#]|\\\\.|\"([^\\\\\"]|\\\\.)*\"|'[^']*')*"

これは意味が同じで(長さも同じです)、シェル引用の別の方法にすぎません。私は個人的に一重引用符が心配する必要がある唯一の文字なので、最初の方法を好むが、2番目の方法がより読みやすいことがわかります。 、これは他のプログラミング言語で書くのと非常によく似ています。

正規表現は、一致しない引用符を含む行をどのように処理するかわからないことに注意することが重要です。正規表現とまったく一致しないので、sedコマンドは何も削除しませんが、grepコマンドはすべてを削除します。

答え3

このコマンドは機能するはずです。

sed -e '/^#/d;s/[^\/]#.*$//' <file-path>

関連情報