2016-03-20 11 views
0

"//"で始まらない行(つまりC++スタイルのコメント)に対してgrepに正規表現を書き込もうとしません。私は "grep -v"オプションを認識していますが、私はregexだけでこの問題を解決する方法を学ぼうとしています。 文字で始まらない行のためのgreppingに関するさまざまな答えを探して見つけました。文字列で始まらない行についてはgrepの方法もありますが、私はこれらの答えを私の場合、私は私の誤りが何であるか理解していません。"//"で始まらない行のGrep

> cat bar.txt 
hello 
//world 
> cat bar.txt | grep "(?!\/\/)" 
-bash: !\/\/: event not found 

この「イベントが見つかりません」についてはわかりません。私が見つけた答えの1つは、ここでやっていて、やはり失敗している括弧で囲まれた疑問符 - 感嘆符 - 括弧を使いました。

> cat bar.txt | grep "^[^\/\/].+" 
(no output) 

私は角括弧の中にキャレットを使用して、この構文は意味「(キャレット以外の)角括弧で何の不在を検索。私は思う」と説明したもう一つの答えが。+「手段」 1つまたはそれ以上のものがありますが、それが正しいかどうかわかりません。正しいものであれば、 "。*"と区別できます。

一言:簡単に言えば、grepに渡して検索する方法"//"で始まらない行については?

もっと具体的には、 "#include"が "//"で始まらない行を検索しようとしています。

ありがとうございます。

答えて

2

最初の行:


はダブルスラッシュで始まらない行、-v(試合を反転させる)と'^//'は、行の先頭にスラッシュを探すために使用を見つけるには問題はbash(あなたのシェル)からだと伝えます。 Bashは!を見つけて、入力した最後のコマンドを\/\/で開始しようとします。これを避けるには、!をエスケープするか、一重引用符を使用する必要があります。 !の例では、!catを試してください。入力した最後のコマンドはcatで始まります。

/をエスケープする必要はありません。正規表現で特別な意味はありません。また、マッチを逆転させるために複雑な正規表現を書く必要もありません。むしろ、grepに-v引数を指定するだけです。ほとんどの時間はシンプルです。また、grepのためにファイルをcatする必要もありません。 grepにファイル名を付けてください。例えば。

grep -v "^//" bar.txt | grep "#include" 

あなたが本当に正規表現を使用してhungupしている場合は、シンプルなものが文字列^の(試合開始ようになり、空白[[:space:]]*の任意の数、正確に2つのバックスラッシュ/{2}、任意の文字.*の任意の数、 #includeによる)に続く:

grep -E "^[[:space:]]*/{2}.*#include" bar.txt 
0

あなたは-P(perlの)オプションを使用する必要があります。 "//" で始まらない行については

cat bar.txt | grep -P '(?!//)' 
0

を、あなたは(^[^/]{2}.*$)を使用することができます。

+0

* $は'追加正規表現には価値がないし、括弧も使わない。 –

2
  1. あなたはPCREの機能であり、開始アンカーもちろんこの意志はgnu-grepを必要と
  2. なしでは動作しません
  3. あなたの否定先読み-Pオプションを必要と否定先読みを使用しています。
  4. !を正規表現で使用する場合は、一重引用符を使用する必要があります。それ以外の場合は、正規表現内の!の後ろのテキストで履歴拡張が試行されます。理由は!\/\/: event not foundです。

だからあなたが使用することができます。

grep -P '^(?!\h*//)' file 
hello 

\h試合0以上の水平空白を。

-Pまたは非GNU grepをしないとあなたがgrep -v使用することができます。

grep -v '^[[:blank:]]*//' file 
hello 
2

//(または/* ...)が付いていない#include行を見つけるには、使用することができます。

grep '^[[:space:]]*#[[:space:]]*include[[:space:]]*["<]' 

正規表現は、行の先頭、オプションのスペース、#、オプションのスペース、include、オプションのスペース、およびまたはのいずれかを探します。。あなたは、ソフトウェアが、このような表記法を含む対処しなければならない場合(a)は、あなたが私の同情を持っていると、

#/*comment*/include/*comment*/<stdio.h> 
#\ 
include\ 
<stdio.h> 

:それは、次のような正当しかし稀であるなど#include MACRO_NAMEなどの線、およびシュートの場合を除くすべての#include行を検索します(b)#include行を検索する前にコードをより正統なスタイルに修正します。あなたはその後、マクロ名バリアントをピックアップし、混乱の最小限のチャンス、との最終[[:space:]]*["<]を省略することができ

/* Do not include this: 
#include <does-not-exist.h> 
*/ 

:それは、次のような偽陽性をピックアップします。

grep -v '^//' 
0

あなたはこのためgrep -vが気に入らない場合は、あなただけのawkを使用することができます。

awk '!/^\/\//' file 

awkは正規表現ではなく複合条件をサポートしているので、grekよりもawkとマッチさせたいものを指定するほうが簡単です。グレップで任意の順序でabを検索するには:AWKで

grep -E 'a.*b|b.*a` 

ながら:。ちょうど1または0の文字と添付 `を含む行を見つけられないでしょう

awk '/a/ && /b/'