ファイルからすべてのコメントを削除するにはどうすればよいですか?


21

コメント付きのファイルがあります:

foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this

コメントされていないコードをすべて印刷したいだけです。

foo
bar
stuff
morestuff
evenmorestuff

ファイルからコメントを取り除くことができることはとても重要です...それを行う良い方法は何ですか?


1
grepを使用して行の一部を削除することはできません。あなたはこのためにsedを使用することができます
miracle173

2
テキストと例は矛盾しています。コメントアウトされている行について書きますが、最後の行から明らかに行の部分を意味します。そして、コメント付きの最初の行はEOLを含めて削除され、2番目の行は削除される可能性がありますが、それが最後の行であるため明確ではありません。「コメントアウトされた行」を正確に書き直して、例を明確にしてください。
アントン14

5
を使用してみてください awk -F\# '$1!="" { print $1 ;} '
アルケマール14

2
ラインはどのようecho '#' # output a #に処理されますか?
クサラナナンダ

3
@Questionmark私は賢いかもしれませんが、シェル文法文法パーサーを書いているわけではありません。
クサラナナンダ

回答:


40

すべてのコメントを削除する1つの方法はgrep-oオプションで使用することです。

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

どこで

  • -o:行の一致した部分のみを出力します
  • 最初^:行の始まり
  • [^#]*#0回以上繰り返される以外の任意の文字

空の行も削除されますが、スペースのみの行は残ることに注意してください。


2
私は使用するだろうgrep -v '^#' file > newfilewithoutcomments
バジルスタリンケビッチ

1
これはシェルスクリプトの一般的な方法ではないことに注意してくださいsomvar='I am a long complicated string ## with special characters' # and I am a comment。たとえば、行は正しく処理されません。
ワイルドカード

このバリアントは(Macで)私に適しています:grep -o '^[^#].*' file
Pierz

コメントはなくなりましたが、出力の代わりに大量の空白が表示されていますか?sedソリューションには1つの空白行しかありませんが、何かが足りない限り、他の答えを使用するための堅実な議論のようです?
Jバリン

@JBallin grep多分エイリアスを定義しましたか?サンプル入力の後にスペースが表示される場合は、に変更grepしてみてくださいcommand grep
-jimmij

31

sedはこれよりもはるかに良い仕事をすることができると信じていますgrep。このようなもの:

sed '/^[[:blank:]]*#/d;s/#.*//' your_file

説明

  • sedデフォルトでファイルを1行ずつ見て、引用符で変換を適用した後、各行を印刷します。(sed '' your_fileすべての行を変更せずに印刷します)。
  • ここではsed、各行で実行する2つのコマンドを提供しています(セミコロンで区切られています)。
  • 最初のコマンドは次のとおりです/^[[:blank:]]*#/d。英語では、行の先頭のハッシュ(先頭に任意の数の空白が続く)と一致する場合、その行を削除します(印刷されません)。
  • 2番目のコマンドは次のとおりs/#.*//です。つまり、英語では、ハッシュマークに続いて、(行の最後まで)できる限り多くのものを何も(最後の2つの間に空スペースはない)に置き換えます//
  • 要約すると、これはファイル全体で実行され、コメントのみで構成される行が削除され、その後に残った行にはコメントが削除されます。

1
また、文字列内のハッシュの後に見つかったものを削除しますか?例えばmystring="Hello I am a #hash" なります mystring="Hello I am a"
javadba

@javadba、はい、しかしその時点で完全なパーサーを使用することもできます。引用符と変数の割り当ては理解できるがコメントを処理できないこのデータを使用するのは何ですか?(これが、crontab先頭の空白の有無にかかわらず全行コメントのみを許可し、行の末尾のコメントを許可しないなどの多くの構成ファイルの理由です。ロジックは非常に簡単です。 crontabコメントストリッパーの場合。)
ワイルドカード

素晴らしい答え、これはユーティリティと複雑さのバランスが取れているように見えますが、一般的なユースケースの広い範囲では複雑ですが、前もって#(列1から)直接行を削除するだけでよいことがわかっている場合、sed以上の利点はありますgrep -v "^#"か?
RBF06

4

sedコマンドを使用して、必要な出力を実現できます。以下のコマンドは私のためにトリックを行っていました。

sed 's/#.*$//g' FileName

どこで

  • #.*$-Regexpは#、行の終わりまでで始まるすべての文字列をフィルタリングします

ここでこれらの行を削除する必要があるので、空に置き換えて「置換」部分をスキップします。

  • g -ファイルの終わりに達するまでパターンの繰り返し検索に言及する。

sedの一般的な構文: s/regexp/replacement/flags FileName


2
注:この場合、4行目は新しい行に置き換えられます。
αғsнιη

1
そのsedコマンドを含むスクリプトでそれを試してみてください...
Kusalananda

それは処理しませんprint "#tag" # Print a hashtag.
Ray Butterworth

3

他の人が指摘しているように、スクリプトの一部がコメントのように見えても実際にはそうでない場合、sedなどのテキストベースのツールはうまく機能しません。たとえば、文字列内で#を検索することも、一般的な$#andを検索することもできます${#param}

私はshfmtというシェルフォーマッターを作成しました。これには、コードを縮小する機能があります。これには、コメントの削除などが含まれます。

$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'

パーサーとプリンターはGoパッケージです。したがって、カスタムソリューションが必要な場合は、20行のGoプログラムを作成して、希望どおりの方法でコメントを削除するのはかなり簡単です。


2

次のような反転一致を使用できます。

    #grep -v "#" filename

-v、--invert-match一致しないラインを選択するために、一致の感覚を反転します。(-vはPOSIXで指定されます。)


2
@alinh回答をレビューしていただきありがとうございます。質問には、行の先頭だけでなく、ファイル内の任意の場所が必要であることに注意してください。これは、上記の質問で彼/彼女の期待される結果にも示されています。行の先頭のみを探す場合、私の答えは間違っています。
ラザ

zzz。私の悪い、最後の行が表示されませんでした:(
alinh

1
これevenmorestuffにより、OPの例で始まる行が完全に削除されます。
ジョセフR. 14

@JosephR。良いキャッチ。私は以前それを見逃した。この場合grep -o '^[^#]*' file、最適なソリューションになります。これは、jimmijによって既に説明されています。レビューをありがとう
ラザ14

それは処理しませんprint "#tag" # Print a hashtag.
Ray Butterworth

2

私はジョセフの答えが好きですが、//コメントも削除する必要があったので、少し修正してredhatでテストしました

# no comments alias
alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings"

# example
cat SomeFile | nocom | less

文字列を使用するよりも空白行を削除するより良い方法があるはずですが、それは私が使用した迅速で汚い解決策でした。

-乾杯


それは処理しませんprint "#tag" # Print a hashtag.
Ray Butterworth


1
cat YOUR_FILE | cut -d'#' -f1

#列セパレータとして使用し、最初の列のみを保持します(以前のすべて#)。


1
YOUR_FILEがこれらのコマンドを含むスクリプトである場合、スクリプトはcat YOUR_FILE | cut -'その行のファイルに残します。
クサラナナンダ

1

次のような式を使用

egrep -v "#|$^" <file-name> 

:-v:一致を反転します

:#:#で始まるすべての行に一致します

:$ ^:すべての空白行に一致します


1
いいえ、これ#は行のどこにでも一致し、行全体を削除します。
-ilkkachu

1

最適な解決策は、次のコマンドを使用することです。

sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf

-iはインプレース編集ですが、プレフィックスの直後にsedがバックアップを作成するように指示します。この場合、日付の拡張子(ntp.conf.date)を使用して、それぞれアドレススペースを使用して2つのコマンドを実行します。最初のコマンドはコメント行を削除し、2番目のコマンドは最初の行とセミコロンで区切って、空行を削除します。

私はこの解決策を見つけました:theurbanpenguin.com


0

他の答えはどれもこの正義を行っていないようで、空行のままにするか、コメントが最初の文字にない行に残します。私はこれを使用することになりました:

cat << EOF >> ~/.bashrc
alias nocom='sed -e "/^\s*#/d" -e "/^\s*$/d"'
EOF

これはエイリアスを設定するので、それを覚える必要はありません(最初は不可能です)。新しいセッションを開くと、新しいnocomコマンドが表示されます。その後、あなたはちょうどすることができます

nocom /etc/foobar.conf

乾杯。


1
.*$最初の正規表現でのマッチングにはあまり意味がありません。アンカーは有用ではなく、置換で使用するために一致したテキストをキャプチャしていません。使用するだけ^\s*
ジェフシャラー

それは処理しませんprint "#tag" # Print a hashtag.
レイバターワース


-1

私は自分のために働くものを投稿しており、説明を読んで他の人を読んだ後、最も理にかなっているようです。いくつかの投稿が近づきましたが、まだコメントできませんでした(私は初心者なので):

grep -E -v "(^#.*|^$)" filename
  • -E = egrepを使用するのと同様に、次のパターンを正規表現として解釈します
  • -v =パターンの反転を印刷します(式と一致しない行が印刷されます)
  • "(^#.*|^$)"=これには、ORステートメントを指定するパイプがあります。この式は、#(およびそれ以降の)OR で始まる行、または行の先頭と末尾の間にゼロ文字が含まれる行を出力することを示します。

-v画面上で起動しない文字を任意の行になることの反転を、印刷します#


それは処理しませんprint "#tag" # Print a hashtag.
レイバターワース

ああ、もちろん... それを指摘してくれてありがとう。pam.d configsなどの典型的なlinux構成ファイルに関する答えを探していたので、それについては考えていませんでした。コードと同じ行にあるコメントを見つけて削除するように調整する必要があると思います。上記の私の特定の問題に対するおそらくより良い解決策を見ました:egrep -v "#| $ ^"
jackbmg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.