web-dev-qa-db-ja.com

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

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

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

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

foo
bar
stuff
morestuff
evenmorestuff

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

25
Questionmark

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

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

どこ

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

空の行も削除されますが、スペースのみの行は残ります。

42
jimmij

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

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

説明

  • sedはデフォルトでファイルを1行ずつ調べ、引用符で変換を適用した後に各行を出力します。 (sed '' your_fileは、すべての行を変更せずに印刷します)。
  • ここでは、各行で実行する2つのコマンドをsedに指定しています(セミコロンで区切られています)。
  • 最初のコマンドは言う:/^[[:blank:]]*#/d。英語では、行がその先頭のハッシュと一致する場合(先頭に空白がいくつもある場合)、その行を削除します(印刷されません)。
  • 2番目のコマンドはs/#.*//。つまり、英語では、ハッシュマークの後ろに、行末までの(つまり、最後の2つの//)。
  • 要約すると、これはファイル全体で実行され、コメントのみで構成される行を削除します。その後に残った行があると、コメントが取り除かれます。
32
Joseph R.

他の人が指摘したように、スクリプトの一部がコメントのように見えても実際にはそうでない場合、sedおよびその他のテキストベースのツールはうまく機能しません。たとえば、文字列内の#や、かなり一般的な$#および${#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プログラムを記述して、希望どおりにコメントを削除するのはかなり簡単です。

4
Daniel

Sedコマンドを使用して必要な出力を得ることができます。以下のコマンドは私のためのトリックを行いました。

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

どこ

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

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

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

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

4
Sridhar DD

これは私のために働いた

sed -i.old -E  "/^(#.*)$/d" file 
1
David Okwii

ジョセフR.の2番目の回答に続いて、/^$/dを追加して空白行を削除します。

sed '/^[[:blank:]]*#/d;s/#.*//;/^$/d'
1
Pierre-Damien

入力例

cat example.sh
#!/bin/bash
# example script

echo "# test";# echo "# test"

# check the first parameter
if [ "$1" = "#" ]; then 
  # test couple of different cases
  echo "#"; # output # character 
  echo '\#'; # output # character '#' for test purpose
  echo \#\#\#; # comment # comment # comment '# comment'
  echo \#
  echo \#;
  echo \#; # comment
fi
# end of the script

コメントを削除

sed -e '1{/^#!/ {p}}; /^[\t\ ]*#/d;/\.*#.*/ {/[\x22\x27].*#.*[\x22\x27]/ !{:regular_loop s/\(.*\)*[^\]#.*/\1/;t regular_loop}; /[\x22\x27].*#.*[\x22\x27]/ {:special_loop s/\([\x22\x27].*#.*[^\x22\x27]\)#.*/\1/;t special_loop}; /\\#/ {:second_special_loop s/\(.*\\#.*[^\]\)#.*/\1/;t second_special_loop}}' example.sh

結果

cat example.sh
#!/bin/bash

echo "# test";

if [ "$1" = "#" ]; then 
  echo "#"; 
  echo '\#'; 
  echo \#\#\#; 
  echo \#
  echo \#;
  echo \#;
fi

ソースでそれがどのように機能するかを読みます: https://blog.sleeplessbeastie.eu/2012/11/07/how-to-remove-comments-from-a-Shell-script/

1
Eduardo Cuomo

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

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

# example
cat SomeFile | nocom | less

文字列を使用するよりも空白行を削除する方が良い方法があるに違いありませんが、それは私が使用した迅速で汚れたソリューションでした。

-乾杯

1
brandon

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

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

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

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

1
jyoti

あなたはこのように逆マッチを使うことができます:

    #grep -v "#" filename

-v、--invert-match一致の意味を反転して、一致しない行を選択します。 (-vはPOSIXで指定されています。)

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

それは使用しています #を列セパレータとして使用し、最初の列のみを保持します(つまり、#)。

1
Alexey

私は他の人たちを読んで説明をした上で、自分にとって有効で最も意味のあるものを投稿しています。いくつかの投稿が近づきましたが、私はまだコメントできませんでした(私は初心者なので):

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

_-v_は、その反転を画面に出力します。これは、_#_で始まらない文字を含む行です。

0
jackbmg

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

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

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

nocom /etc/foobar.conf

乾杯。

0
bviktor

次のような表現を使用

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

:-v:反転一致を行います

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

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

0
aditya