Grepは語幹を検索し、単語のみを印刷します(行を除く)。

Grepは語幹を検索し、単語のみを印刷します(行を除く)。

正規表現で見つかった一致する単語だけを印刷しようとしています。以下では、OPENSSL_NO_*ソースコードにすべてのオプションを表示したいと思います。

$ grep -IR OPENSSL_NO
fuzz/asn1.c:#ifndef OPENSSL_NO_RFC3779
fuzz/asn1.c:#ifndef OPENSSL_NO_RFC3779
fuzz/asn1.c:#ifndef OPENSSL_NO_CMS
fuzz/asn1.c:#ifndef OPENSSL_NO_DH
fuzz/asn1.c:#ifndef OPENSSL_NO_EC
fuzz/asn1.c:#ifndef OPENSSL_NO_RFC3779
fuzz/asn1.c:#ifndef OPENSSL_NO_OCSP
fuzz/asn1.c:#ifndef OPENSSL_NO_TS
fuzz/asn1.c:#ifndef OPENSSL_NO_DH
fuzz/asn1.c:#ifndef OPENSSL_NO_DSA
...

完全な単語だけを印刷して出力を切り捨てようとすると、次のようになります。

$ grep -oIR "OPENSSL_NO*"
fuzz/asn1.c:OPENSSL_NO
fuzz/asn1.c:OPENSSL_NO
fuzz/asn1.c:OPENSSL_NO
fuzz/asn1.c:OPENSSL_NO
fuzz/asn1.c:OPENSSL_NO
...

awkを試してみると、行全体が印刷されます。

$ grep -IR OPENSSL_NO | awk '/OPENSSL_NO[_A-Z0-9_]/{ print $0 }'
fuzz/asn1.c:#ifndef OPENSSL_NO_RFC3779
fuzz/asn1.c:#ifndef OPENSSL_NO_RFC3779
fuzz/asn1.c:#ifndef OPENSSL_NO_CMS
fuzz/asn1.c:#ifndef OPENSSL_NO_DH
fuzz/asn1.c:#ifndef OPENSSL_NO_EC
...

そして:

$ grep -IR OPENSSL_NO | awk '/\<OPENSSL_NO\>'
awk: line 1: runaway regular expression /\<OPENSSL_ ...

そして:

$ grep -Eo -IR 'OPENSSL_NO_[A-Z0-9_]'
fuzz/asn1.c:OPENSSL_NO_R
fuzz/asn1.c:OPENSSL_NO_R
fuzz/asn1.c:OPENSSL_NO_C
fuzz/asn1.c:OPENSSL_NO_D
fuzz/asn1.c:OPENSSL_NO_E

そして:

$ grep -IR OPENSSL_NO | sed -n 's/.*\(OPENSSL_NO\).*/\1/p'
OPENSSL_NO
OPENSSL_NO
OPENSSL_NO
OPENSSL_NO
OPENSSL_NO
...

単語を一致させてからその単語だけを印刷するには?


質問が多すぎるということを考えると、これは明らかに痛みを伴う仕事です。次は[簡単? ]質問に関するさまざまな質問:

ベストアンサー1

*正規表現とはどういう意味ですか?0個以上の先行原子*シェルワイルドカード演算子と混同しています。0文字以上

OPENSSL_NO_*OPENSSL_NO後ろにゼロ以上の下線があることを示します。

あなたが望むもの:

grep -o 'OPENSSL_NO_.*'

.単一文字に一致する正規表現演算子はどこにありますか?

または:

grep -o 'OPENSSL_NO_[[:alnum:]]*'

ゼロ個以上の英数字(ロケールでサポートされているすべてのアルファベットスクリプト)

拡大する正規表現(例grep -E:)にも次のものがあります+1つ以上の先行原子。そして基本的な代わりに正規表現(-Eを除く)を使用できます\{1,\}

一部の実装にはこの意味grepもあります。\w英数字または下線ただし、一部の実装の一部のバージョンではこれに限定されますA-Za-z0-9

とにかく標準-o的な-Rオプションではないことに注意してください。 POSIXlyでは、次のことができます。

sed -n 's/.*\(OPENSSL_NO_[[:alnum:]_]\{1,\}\).*/\1/p' < file

(1行に1回のみ発生する可能性があり、複数回発生した場合は一番右の項目のみが表示されます。)

ファイル名は印刷されません。これを行うには、次のものを使用できますawk

find . -name '*.[hc]' -type f -exec awk 'match($0, /OPENSSL_NO_[[:alnum:]_]+/) {
  print FILENAME": "substr($0, RSTART, RLENGTH)}' {} +

おすすめ記事