grep
Debianの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
します。つまり、行の先頭から始めるか、「単語ではない」文字が前になければならず、行の末尾で終わるか、後に続く必要があることを意味します。 「シルバー」文字で。grep
fruit
ただし、マニュアルページによると、「単語」の文字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
実装では、-P
Perl と同様の正規表現に切り替えることを選択できます。
perl
はっきり周りを見てください前または後に一致する項目があるかどうかを確認するために使用される演算子。
grep -w word
grep -P '(?<!\w)word(?!\w)'
それぞれと(?<!pattern)
(?!pattern)
否定的に振り返るそして最初オペレーター。
これを単語コンポーネントと考えるには、-
次のように変更できます。
grep -P '(?<![\w-])fruit(?![\w-])'
orが後ろにあるため、foo fruit bar
orと一致しますfoo/fruit/bar
が一致foo/fruit
しません。foo/fruit-bar
fruit
-
またはしかしどんなキャラクターでも/
:
grep -P '(?<![^/])fruit(?![^/])'
またはスペースで区切られた単語:
grep -P '(?<!\S)word(?!\S)'
(ここでは\S
POSIX[^\s]
と同じように空白[^[:space:]]
に分類されていない文字です)。