web-dev-qa-db-ja.com

Grepは検索パターンに一致する単語だけを表示できますか?

Grepが検索式に一致するファイルから「単語」を出力する方法はありますか?

たとえば、 "th"のすべてのインスタンスを多数のファイルで見つけたい場合は、次のようにします。

grep "th" *

しかし、出力は次のようになります(太字は私にあります)。

 some-text-file:   猫が座った   mat 
その他のテキストファイル   クイックブラウンフォックス
まだ別のテキストファイル:私は願っています この  それを説明します 徹底的に

同じ検索を使用して出力したいのは、次のとおりです。

the
the
the
this
thoroughly

これはgrepを使って可能ですか?それとも別のツールの組み合わせを使用しますか?

565
Neil Baldwin

Grep -oを試してください。

grep -oh "\w*th\w*" *

編集:Philのコメントからマッチング

ドキュメントから

-h, --no-filename
    Suppress the prefixing of file names on output. This is the default
    when there is only  one  file  (or only standard input) to search.
-o, --only-matching
    Print  only  the matched (non-empty) parts of a matching line,
    with each such part on a separate output line.
784
Dan Midwood

クロスディストリビューションの安全な答え(windows minGW?を含む)

grep -h "[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' '\n' | grep -h "[[:alpha:]]*th[[:alpha:]]*"

-oオプションを含まないgrepの古いバージョン(2.4.2など)を使用している場合。上記を使用してください。そうでなければ、以下のバージョンを維持するためにもっと単純なものを使用してください。

Linuxクロスディストリビューションの安全な答え

grep -oh "[[:alpha:]]*th[[:alpha:]]*" 'filename'

要約すると-ohはファイルの内容ではなく(ファイル名ではなく)正規表現にマッチするものを出力します。これはvim/etcで正規表現が機能することを期待するのと同じです。あなたへ! Perlの構文ではなくPOSIXを使い続ける限り(下記参照)

grepのマニュアルの詳細

-o      Print each match, but only the match, not the entire line.
-h      Never print filename headers (i.e. filenames) with output lines.
-w      The expression is searched for as a Word (as if surrounded by
         `[[:<:]]' and `[[:>:]]';

元の答えが誰にとってもうまくいかない理由

\wの使用法は、その拡張された「Perl」構文として、プラットフォームごとに異なります。そのため、POSIX文字クラスでの作業に限定されているgrepインストールは[[:alpha:]]を使用し、Perlの\wと同等のものではありません。 正規表現についてはウィキペディアのページを見てください

最終的に、grepのプラットフォーム(元のもの)に関係なく、上記のPOSIXの答えはより信頼性が高くなります。

-oオプションなしのgrepのサポートに関しては、最初のgrepは関連する行を出力し、trは空白を新しい行に分割し、最後のgrepはそれぞれの行に対してのみフィルタをかけます。

(シモンズ:私は今ではほとんどのプラットフォームを知っています、\ wのためにパッチを当てられたであろう.... ....しかし遅れるものが常にあります)

@AdamRosenfield回答からの "-o"回避策の功績

76
PicoCreator

スペースを改行に変換してからgrepすることができます。

cat * | tr ' ' '\n' | grep th
41
Adam Rosenfield

単にawk、ツールの組み合わせは不要です。

# awk '{for(i=1;i<=NF;i++){if($i~/^th/){print $i}}}' file
the
the
the
this
thoroughly
33
ghostdog74

思ったより簡単です。これを試して:

egrep -wo 'th.[a-z]*' filename.txt #### (Case Sensitive)

egrep -iwo 'th.[a-z]*' filename.txt  ### (Case Insensitive)

どこで、

 egrep: Grep will work with extended regular expression.
 w    : Matches only Word/words instead of substring.
 o    : Display only matched pattern instead of whole line.
 i    : If u want to ignore case sensitivity.
24

マッチングおよびPerl専用のgrepコマンド

grep -o -P 'th.*? ' filename
10
Raghu

私はawkが文法を覚えるのが難しいことに満足していませんでしたが、これを行うために1つのユーティリティを使うという考えが好きでした。

Ack(またはUbuntuを使用している場合はack-grep)がこれを簡単に実行できるように思えます。

# ack-grep -ho "\bth.*?\b" *

the
the
the
this
thoroughly

-hフラグを省略すると、次のようになります。

# ack-grep -o "\bth.*?\b" *

some-other-text-file
1:the

some-text-file
1:the
the

yet-another-text-file
1:this
thoroughly

おまけとして、--outputフラグを使うと、私が見つけた最も簡単な構文を使って、より複雑な検索を行うことができます。

# echo "bug: 1, id: 5, time: 12/27/2010" > test-file
# ack-grep -ho "bug: (\d*), id: (\d*), time: (.*)" --output '$1, $2, $3' test-file

1, 5, 12/27/2010
8
Beau
cat *-text-file | grep -Eio "th[a-z]+"
8
Mumbling Mac

"icon-"で始まるすべての単語を検索するには、次のコマンドを実行してください。ここでは Ack を使用していますが、これはgrepに似ていますが、より良いオプションと素晴らしいフォーマットです。

ack -oh --type=html "\w*icon-\w*" | sort | uniq
4
Sandeep

pcregrep を試すこともできます。 grep -wオプションもありますが、場合によっては期待通りに動作しません。

から ウィキペディア

cat fruitlist.txt
Apple
apples
pineapple
Apple-
Apple-fruit
fruit-Apple

grep -w Apple fruitlist.txt
Apple
apple-
Apple-fruit
fruit-Apple
3
Maciek Sawicki

私は同様の問題を抱えていました。grep/patternの正規表現と "マッ​​チしたパターンが見つかりました"を出力として探していました。

最後に、オプション-oを付けてegrep(grep -eまたは-Gと同じ正規表現を使用しても同じ結果が得られなかった)を使用しました。

だから、私はそれが(私は正規表現のマスターではない)に似たものになるかもしれないと思う:

egrep -o "the*|this{1}|thoroughly{1}" filename
3
keebOo

ripgrep

これがripgrepを使った例です:

rg -o "(\w+)?th(\w+)?"

thに一致するすべての単語に一致します。

0
kenorb
$ grep -w

grepのmanページからの抜粋:

-w: 単語全体を構成する一致を含む行のみを選択します。テストは、一致するサブストリングが行の先頭にあるか、またはWord以外の構成文字が前にあるかのいずれかでなければならないというものです。

0
pl1nk