一致する行だけでなく、すべての行を出力するようにgrepを説得する


121

次のファイルがあるとします。

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4

デフォルトでgrepは、検索語を含む各行を返します。

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4

--colorパラメータを渡すと、grep検索式に一致する行の部分が強調表示されますが、式を含む行のみが返されます。grepソースファイルのすべての行を出力する方法はありますが、一致を強調表示しますか?

これを達成するための私の現在の恐ろしいハック(少なくとも10000以上の連続した行が一致しないファイルでは):

$ grep -B 9999 -A 9999 test test

2つのコマンドのスクリーンショット

これgrepを達成できない場合、同じ機能を提供する別のコマンドラインツールはありますか?私はをいじりましackたが、オプションもありません。


1
可能なクロスサイトの複製:stackoverflow.com/questions/981601/…一番上の答えは両方で同じです。
Ciro Santilli新疆改造中心法轮功六四事件14

1
.Iの-C 9999代わりに使用できます-A 9999 -B 9999。常に次のことを行います。grep -C 9999 pattern file
neo

回答:


184
grep --color -E "test|$" yourfile

ここで行っているのは、$パターンとテストパターンとのマッチングです。明らか$に色付けするものがないため、テストパターンのみが色を取得します。-Eただ、拡張正規表現のマッチングをオンにします。

このように簡単に関数を作成できます:

highlight () { grep --color -E "$1|$" "${@:1}" ; }

14
すごいね!
gvkv

3
そして機能として:highlight () { grep --color -E "$1|$" $2 ; }。使用法:highlight test yourfile
ステファンLasiewski

2
@StefanLasiewski:"$2"引用する必要もあります。
デニスウィリアムソン

6
より良い可能性があります:highlight () { grep --color -E "$1|$" "$@" }名前に空白文字を含むファイル複数のファイルを許可します。
マイクデシモーネ

15
@MikeDeSimone-しかし、それは"$1"ファイルにも含まれます。使用highlight () { grep --color -E "$1|$" "${@:1}" }
クリスダウン

40
ack --passthru --color string file

UbuntuおよびDebianの場合、ackの代わりにack-grepを使用します

ack-grep --passthru --color string file

1
ああ、それは明らかにmanページにあります。わたしは目が見えない。ありがとう
マイケル・ミロゼック

grapのパターンは、--regexp string;で明示的に指定できます。ack / ack-grepに相当するものは--match string
-Rhubbarb

ack --passthruperlでシミュレートするには:grep_passthrough () { ! perl -ne "print; \$e ||= /$@/; END{{exit \$e}}"; }
ルーカスサイモン

ack --passthruストリームでも動作します!たとえば、ifconfig | ack --passthru inet
honkaboy

13

これを適切かつ移植可能にする別の方法grep(受け入れられた答えのように2つの正規表現を交互に使用する以外に)は、nullパターン(およびそれぞれnull文字列)を使用することです。標準に従って、スイッチとスイッチの
両方で同等に機能するはずです:-E-F

-E
    Match using extended regular expressions. 
    [...] A null ERE shall match every line.

そして

-F
    Match using fixed strings.
    [...] A null string shall match every line.

だから、単に実行するだけの問題です

grep -E -e '' -e 'pattern' infile

それぞれ

grep -F -e '' -e 'string' infile

1
または単にgrep -F -e '' -e 'string'
ステファンシャゼラス

GNU grep 2.25、busybox grep、および家宝ツールチェストで動作します。
ステファンシャゼラス

私の悪いことに、seq 3 | grep -F -e '' -e 22.27で2だけを出力します(そして2.25ではなく、2.25ではなく、gitヘッドでは出力しません)。のみ-F(-Eなしまたはなし)。IOWでは、バグがあるのは2.26と2.27だけで、-Fがある場合のみです。
ステファンシャゼラス

seq 3 | grep -F -e '' -e '' -e 2 2.27
StéphaneChazelas 17年

1
この回答に記載されている方法は、シンプルで正確で、非常に高速です。あなたが言うように、それは自動的に動作し-F、どの文字が現れるかを心配する必要を軽減しstringます。言及したいかもしれません--color。この回答がページに浮かぶと(投票で表示される場合)、他の回答の前に読む人が増える可能性があります。
エリアケイガン

11

私はそのようなことのために使用する次の機能を持っています:

highlight () {
    perl -pe "s/$1/\e[1;31;43m$&\e[0m/g"
}

内部的にはkindいように見えますが、次のようにすてきで使いやすいです:

cat some_file.txt | highlight some_word

または、もう少し現実的な例の場合:

tail -f console.log | highlight ERROR

1and 3143(後\e[)を異なる値に変更することで、色を好きなものに変更できます(grepでは難しいかもしれませんが、わかりません)。コードを使用することがあるすべての上に場所が、ここでは迅速なイントロです:1つの太字テキストは、31それが赤になり、そして43黄色の背景を提供します。 32または33異なる色、44または45異なる背景になります:あなたはアイデアを得る。5気になっている場合は、(で)点滅させることもできます。

これは特別なPerlモジュールを使用せず、Perlはほぼどこにでもあるので、ほぼどこでも動作することを期待しています。grepソリューションは非常に巧妙ですが、grepの--colorスイッチはどこでも利用できません。たとえば、bashを実行しているSolarisボックスとkshを実行している別のボックス、およびzshを実行しているローカルのMac OS Xマシンでこのソリューションを試しました。すべてうまくいきました。grep --colorしかし、Solarisはソリューションに制約を感じました。

また、ackはすばらしく、まだ発見していない人にはお勧めしますが、私が取り組んでいる多くのサーバーのいくつかにインストールするのに問題があります。(理由を忘れます:必要なPerlモジュールに関連すると思います。)

私はないと思うので、私がきたこれまでのUnixボックスに働いていなかった Perlがインストールされている(組み込み型システム、Linksysのルータを除いて、そのような)私はこれはかなり普遍的に使用可能なソリューションだと思います。


3

Grepを使用する代わりに、Lessを使用できます。

less file

このような検索: /pattern Enter

この意志:

  1. 最初に一致する行までスクロールする
  2. そこから始まるすべての行を出力します
  3. すべての一致を強調表示する

次の一致する行までスクロールするには: n

前の一致する行にスクロールするには: N

ハイライトを切り替えるには: Esc u

また、必要に応じて強調表示の色を変更できます。


2

あなたが試すことができます:

perl -MTERM::ANSIColor -nle '/pattern/ ? print colored($_, 'color') : print' test

ただし、移植性はそれほど高くなく、Perlがインストールされている場合でも、別のモジュールをダウンロードする必要があります。さらに、検索語だけでなく、行全体を色付けします。


2

ripgrep

ripgrepその--passthruパラメーターと共に使用します。

rg --passthru pattern file.txt

有限オートマトン、SIMD、および積極的なリテラル最適化を使用して非常に高速に検索するRustの正規表現エンジンの上に構築されているため、最速のgreppingツールの1つです。

--passthru -一致する行と一致しない行の両方を印刷します。

同様の効果を実現する別の方法は、空の文字列に一致するようにパターンを変更することです。たとえば、を使用して検索しているrg foo場合、rg "^|foo"代わりにusingは検索されたすべてのファイルのすべての行を出力しますが、fooの出現のみが強調表示されます。このフラグは、パターンを変更することなく同じ動作を可能にします。


1

GNU grepに対してこれを行うもっと簡単な方法はありますが、移植性があるとは思いません(つまり、BSD grep):

パイプ内:

cat <file> | grep --color=always -z <query>

ファイル上:

grep --color=always -z <query> <file>

クレジットはここでCyrusの答えになります


1
これは、あなた(そしてサイラス)が考えるほど良い答えではありません。ファイル全体を1行として扱う効果があります。ファイルは非常に大きい場合したがって、(1)、メモリが不足する可能性がある、とファイルパターンを含まない場合(2)全く、何も出力しないだろう。そしてあなたは正しい。普遍的に利用できるわけではありません。(しかし、再び、標準--colorはありません。)
G-Man

これはどのバージョンのgrepでサポートされていますか?grep 2.5.4では、-zが利用できないようです...
Alex

1

これまでに与えられた答えはどれも、ポータブルなソリューションを提供しません。

ここではポータブルで1つの私はシェル関数すでに掲載非標準のツールまたはを提供する非標準の拡張機能を必要としない重複した問題としてクローズでperlackggrep、をgsedbashそして好きなだけPOSIXシェルとPOSIXの必須のユーティリティを必要sedprintf

grepc()
{
  pattern=$1
  shift
  esc=$(printf "\033")
  sed 's"'"$pattern"'"'$esc'[32m&'$esc'[0m"g' "$@"
}

そのように使用できます:

grepc string_to_search [file ...]

ハイライトの色は、sedコマンド引数で次のコードのいずれかを使用して調整できます(ここでは32mが緑色です)。

30m black
31m red
33m yellow
34m blue
35m magenta
36m cyan
37m white
7m reverse video

1端末がANSIカラーエスケープシーケンスをサポートしている限り。


0

sedバージョンは、両方で動作しますbashash

#highlight
hsed(){
    local pattern="$1"
    shift
    local r=`echo -e '\e'[31m`
    local c=`echo -e '\e'[0m`
    sed "s:${pattern//:/\:}:$r\0$c:g" "$@"
}

0

OPが要求しgrep、それが私が推奨するものです。しかしsed、記録のためにで問題を解決しようと懸命に努力した後、ここに簡単な解決策があります:

sed $'s/main/\E[31m&\E[0m/g' testt.c

または

cat testt.c | sed $'s/main/\E[31m&\E[0m/g'

main赤でペイントします。

  • \E[31m :赤色の開始シーケンス
  • \E[0m :完成したカラーマーク
  • & :一致したパターン
  • /g :最初の単語だけでなく、行のすべての単語
  • $'string' エスケープ文字が解釈されたbash文字列です

grepに関して^は、$(行末)の代わりに(行頭)を使用しても機能します。例:

egrep "^|main" testt.c

そして、私が推奨しないこのクレイジーなエイリアスを示すために、あなたはオープンクオートを許可することさえできます:

alias h='egrep -e"^|'
h main" testt.c
cat testt.c | h main"

すべての仕事!:)引用符を閉じるのを忘れても心配しないでください。bashは「継続行文字」であなたを覚えています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.