「grep -w」がハイフン/マイナス記号(「-」)が次の単語と一致するのはなぜですか?

「grep -w」がハイフン/マイナス記号(「-」)が次の単語と一致するのはなぜですか?

grepDebianのBashスクリプトでコマンドを使用する方法について質問したいと思います。

次の行を含むサンプルファイルがあります。

/fruit-/apple.txt
/fruit-/banana.txt
/fruit-/samples
/vegetables-/carrot.txt
/vegetables-/garlic.txt

wordを含むすべての行を選択したいと思いますfruit-

次のコマンドを呼び出すことができます。

grep -w "fruit-" file.txt

出力は次のとおりです。

/fruit-/apple.txt
/fruit-/banana.txt
/fruit-/samples

ただし、次のコマンドを使用する場合:

grep -w "fruit" file.txt

また、上記と同じ出力を取得します。しかし、これは間違っています。出力はゼロでなければなりません。入力モードがないためです-

なぜ適切にgrep治療しないのです-か?

答え1

このオプションは、「単語」に一致する行のみを検索するように指示-wします。つまり、行の先頭から始めるか、「単語ではない」文字が前になければならず、行の末尾で終わるか、後に続く必要があることを意味します。 「シルバー」文字で。grepfruit

ただし、マニュアルページによると、「単語」の文字grepは次のようになります。

単語を構成する文字は、文字、数字、下線です。

-これは「単語」文字を意味し、一致アルゴリズムが到着時に停止するため、fruit-「単語検索」と一致します。fruit-

今、最初の2行の間に内容がある行だけを選択したいようです。/ 正確に fruit、相対的パターンが含まれています。 fruit。そのような場合は、一致をより明確にする必要があります。

  • を使用すると、grep次のように言うことができます。
    grep "^/fruit/" file.txt
    
    これにより、パターンが行の先頭に固定され、-その後に来ない行のみが許可されますfruit
  • または、awkコレクションを/フィールド区切り文字として使用します。
    awk -F/ '!$1&&$2=="fruit"' file.txt
    
    /最初のフィールドが空で(つまり、aで始まる)、2番目のフィールドが正確にある行のみが許可されますfruit

答え2

@AdminBee何かを明確にしました言葉意味grep、この文脈で単語の他の定義を使用するように指示する方法を追加します。

grep -w wordややword前後に単語文字がないsを探します。

一部のgrep実装では、-PPerl と同様の正規表現に切り替えることを選択できます。

perlはっきり周りを見てください前または後に一致する項目があるかどうかを確認するために使用される演算子。

grep -w wordgrep -P '(?<!\w)word(?!\w)'それぞれと(?<!pattern)(?!pattern)否定的に振り返るそして最初オペレーター。

これを単語コンポーネントと考えるには、-次のように変更できます。

grep -P '(?<![\w-])fruit(?![\w-])'

orが後ろにあるため、foo fruit barorと一致しますfoo/fruit/barが一致foo/fruitしません。foo/fruit-barfruit-

またはしかしどんなキャラクターでも/:

grep -P '(?<![^/])fruit(?![^/])'

またはスペースで区切られた単語:

grep -P '(?<!\S)word(?!\S)'

(ここでは\SPOSIX[^\s]と同じように空白[^[:space:]]に分類されていない文字です)。

関連情報