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

두 명령의 스크린 샷

grep이를 수행 할 수없는 경우 동일한 기능을 제공하는 다른 명령 줄 도구가 있습니까? 나는 바이올린을 사용 ack했지만 옵션이없는 것 같습니다.


1
크로스 오버 사이트 중복 가능성 : stackoverflow.com/questions/981601/… 최고 답변은 두 가지 모두 동일합니다.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

1
.I -C 9999대신 -A 9999 -B 9999항상 사용할 수 있습니다 :grep -C 9999 pattern file
neo

답변:


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

여기서하고있는 것은 $패턴과 테스트 패턴과 일치하는 것 입니다. 분명히 $색상을 지정할 것이 없으므로 테스트 패턴 만 색상을 얻습니다. 는 -E단지 확장 된 정규식 일치를 켭니다.

다음과 같이 쉽게 함수를 만들 수 있습니다.

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

14
대단해!
gvkv

3
그리고 함수로서 : highlight () { grep --color -E "$1|$" $2 ; }. 사용법 :highlight test yourfile
Stefan Lasiewski

2
@StefanLasiewski : "$2"도 인용해야합니다.
Dennis Williamson

6
더 나은이 될 수있다 : highlight () { grep --color -E "$1|$" "$@" }이름에 공백을 가진 파일을 허용하는 여러 파일.
Mike DeSimone

15
@MikeDeSimone-그러나 "$1"파일 에도 있습니다 . 사용highlight () { grep --color -E "$1|$" "${@:1}" }
Chris Down

39
ack --passthru --color string file

Ubuntu 및 Debian의 경우 ack 대신 ack-grep을 사용하십시오.

ack-grep --passthru --color string file

1
아, 그것은 맨 페이지에 분명히 있습니다. 나는 장님입니다. 감사합니다
Michael Mrozek

grap 패턴은 다음과 같이 명시 적으로 지정할 수 있습니다 --regexp string. ack / ack-grep와 동등한 값은--match string
Rhubbarb

ack --passthrugrep_passthrough () { ! perl -ne "print; \$e ||= /$@/; END{{exit \$e}}"; }
펄로

ack --passthru스트림에서도 작동합니다! 예 :ifconfig | ack --passthru inet
honkaboy

12

또 다른 방법은이 일을 제대로 하고 이식 으로 grep(허용 대답 같이 교대 두 개의 정규 표현식에를 사용 외에) 널 패턴 (각각 널 (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'.
Stéphane Chazelas

그것은 GNU grep 2.25, busybox grep 및 가보 도구와 함께 작동합니다.
Stéphane Chazelas

좋아, 내 나쁜 seq 3 | grep -F -e '' -e 2것은 2.27에서 2 만 출력하고 2.26은 아니지만 2.25는 아니고 git head는 출력하지 않습니다. -F(-E없이 또는 -E없이) 만 사용 합니다. IOW, 2.26 및 2.27 만 버그가 있고 -F 만 있습니다.
Stéphane Chazelas

seq 3 | grep -F -e '' -e '' -e 2 2.27으로 잘 작동하는 것처럼 보인다
스테판 Chazelas가

1
이 답변에 제공된 방법은 간단하고 정확하며 매우 빠릅니다 . 당신이 말한대로 , 그것은 자동으로 작동 -F하므로 어떤 문자가 나타나는지 걱정할 필요가 없습니다 string. 언급하고 싶을 수도 있습니다 --color. 이 답변이 페이지에 뜨면 (투표로 볼 때), 더 많은 사람들이 다른 답변보다 먼저 그것을 읽을 수 있습니다.
Eliah Kagan

11

그런 것들에 사용하는 다음 기능이 있습니다.

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

내부적으로는 추악한 것처럼 보이며 다음과 같이 멋지고 사용하기 쉽습니다.

cat some_file.txt | highlight some_word

또는 좀 더 실제적인 예를 들면 다음과 같습니다.

tail -f console.log | highlight ERROR

1and 3143(after \e[)를 다른 값으로 변경하여 원하는 색상으로 변경할 수 있습니다 (grep로 어려울 수 있습니다-확실하지 않습니다) . 코드 사용에는 모든 이상 장소 ,하지만 여기에 빠른 소개입니다 : 텍스트는이 1 bolds 31가 빨간색하게는, 그리고이 43노란색 배경을 제공합니다. 32또는 33색상이 다를 수 것이고, 44또는 45다른 배경이 될 것입니다 : 당신은 아이디어를 얻을. 5기울어 져 있으면 깜박임 (을 사용하여 )으로 만들 수도 있습니다 .

이것은 특별한 Perl 모듈을 사용하지 않으며 Perl은 거의 어디에나 있으므로 거의 어디에서나 작동 할 것으로 기대합니다. grep 솔루션은 매우 영리하지만 grep의 --color 스위치를 모든 곳에서 사용할 수는 없습니다. 예를 들어 방금 bash를 실행하는 Solaris 상자와 ksh를 실행하는 다른 상자 및 zsh를 실행하는 로컬 Mac OS X 시스템 에서이 솔루션을 시도했습니다. 모두 잘 작동했습니다. grep --color그러나 솔라리스는 그 해결책 에 질식했다 .

또한 ack는 훌륭하며 아직 그것을 발견하지 못한 사람에게 추천하지만, 내가 작업하는 많은 서버 중 일부에 설치하는 데 약간의 문제가 있습니다. (왜 그런지 잊어 버렸습니다 : 필요한 Perl 모듈과 관련이 있다고 생각합니다.)

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 도구 중 하나입니다 .

--passthru -일치하는 줄과 일치하지 않는 줄을 모두 인쇄하십시오.

비슷한 효과를 얻는 또 다른 방법은 빈 문자열과 일치하도록 패턴을 수정하는 것입니다. 예를 들어, rg foo를 사용하여 검색하는 경우 대신를 사용하면 rg "^|foo"검색된 모든 파일에서 모든 줄이 표시되지만 foo 항목 만 강조 표시됩니다. 이 플래그는 패턴을 수정할 필요없이 동일한 동작을 가능하게합니다.


1

GNU grep에 대해이 작업을 수행하는 훨씬 쉬운 방법이 있지만 이식성이 있다고 생각하지 않습니다 (예 : BSD grep).

파이프에서 :

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

파일에서 :

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

크레딧은 여기 Cyrus의 답변으로 갑니다 .


1
이것은 당신 (및 사이러스) 생각만큼 좋은 답변이 아닙니다. 전체 파일을 한 줄로 처리하는 효과가 있습니다. 파일이 매우 큰 경우에 따라서 (1), 메모리 부족의 가능성이있을 수 있으며, 파일 패턴을 포함하지 않는 경우 (2) 모두 , 다음 아무것도 출력되지 않습니다. 그리고 당신 말이 맞아요. 보편적으로 사용할 수 없습니다. (그러나 다시 --color표준 도 아닙니다 .)
G-Man

어떤 버전의 grep이 지원됩니까? grep 2.5.4에서 -z를 사용할 수없는 것 같습니다.
Alex

1

지금까지 제공된 답변 중 어느 것도 휴대용 솔루션을 제공하지 않습니다 .

여기에 이식 내가 쉘 기능을 이미 게시 제공 비표준 도구 또는 비표준 확장을 필요로하지 않습니다 중복 문제로 폐쇄에 perl, ack, ggrep,을 gsed, bash및 좋아하지만 단지 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버전 모두에서 작동 bash하고 ash.

#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.