경기 전후 문자를 잡으시겠습니까?


144

이것을 사용하여 :

grep -A1 -B1 "test_pattern" file

파일에서 일치하는 패턴 전후에 한 줄을 생성합니다. 줄이 아닌 지정된 수의 문자를 표시하는 방법이 있습니까?

내 파일의 줄은 꽤 커서 전체 줄을 인쇄하는 데 관심이 없지만 컨텍스트에서 일치하는 부분 만 관찰합니다. 이 작업을 수행하는 방법에 대한 제안 사항이 있습니까?


답변:


184

3 자 앞뒤 4 자

$> echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}'
23_string_and

5
적은 양의 데이터에 대한 좋은 대답이지만 100자를 초과 할 때 속도가 느리게 시작합니다. 예를 들어, 거대한 XML 파일에서 전후에 {1,200}을 원하고 사용하기에는 너무 느립니다.
Benubird

3
@amit_g의 awk 버전이 훨씬 빠릅니다.
ssobczak

6
Mac OSX에서는 사용할 수 없으므로 실제로는 광범위하게 사용 가능한 솔루션이 아닙니다. -E 버전 (아래에 나열)이 더 나은 솔루션입니다. -P 란 무엇입니까? ... -P, --perl-regexp에서 읽습니다. PATTERN을 Perl 정규식으로 해석합니다 (PCRE, 아래 참조). 이것은 매우 실험적이며 grep -P는 구현되지 않은 기능에 대해 경고 할 수 있습니다.
Xofo

2
OSX에서 다음을 통해 설치 brew install homebrew/dupes/grep하고로 실행하십시오 ggrep.
kenorb

1
@Benubird에 의해 암시 된 바와 같이, 이것은 일치 대상에 대해 원하는 주변이 적당히 넓은 거대한 파일에는 사용하기가 불가능합니다.
matanster

113
grep -E -o ".{0,5}test_pattern.{0,5}" test.txt 

패턴 전후에 최대 5 자까지 일치합니다. -o 스위치는 grep에게 일치 만 표시하고 -E는 확장 정규식을 사용하도록 지시합니다. 표현식 주위에 따옴표를 넣으십시오. 그렇지 않으면 쉘에서 해석 될 수 있습니다.


1
그것이 {} 이렇게에서 길이 2 ^ (8-1)에 덮인있어 흥미 좋은 대답, {0,255}작품 {0,256}제공grep: invalid repetition count(s)
CodeMonkey

일치하는 문자 수 (5-> 25-> 50)를 늘리면 성능이 크게 저하되는 것처럼 보입니다.
Adam Hughes

37

당신은 사용할 수 있습니다

awk '/test_pattern/ {
    match($0, /test_pattern/); print substr($0, RSTART - 10, RLENGTH + 20);
}' file

2
다소 큰 파일도 잘 작동합니다
Touko

4
이것을 사용하여 한 줄에 여러 개의 일치 항목을 찾을 수 있습니까?
koox00

1
중괄호 쌍에서 첫 번째 숫자의 의미는 무엇입니까? "grep -E -o"의 0과 같습니다. {0,5} test_pattern. {0,5} "test.txt"?
Lew Rockwell Fan 2

@ekse의 답변만큼 빠르지 만 정확하지는 않습니다.
Abdollah

24

다음과 같이 의미합니다.

grep -o '.\{0,20\}test_pattern.\{0,20\}' file

?

의 양쪽에 최대 20 개의 문자가 인쇄됩니다 test_pattern. \{0,20\}표기법은 비슷 *하지만 지정 스물 반복 제로 대신 0 개 느껴져요가 -o아니라 전체 라인보다는 단지 경기 자체를 보여 말한다.


이 명령은 나를 위해 작동하지 않습니다 :grep: Invalid content of \{\}
Alexander Pravdin

0

을 사용하면 gawk일치 기능을 사용할 수 있습니다.

    x="hey there how are you"
    echo "$x" |awk --re-interval '{match($0,/(.{4})how(.{4})/,a);print a[1],a[2]}'
    ere   are

perl다음 과 같이 하면보다 유연한 솔루션을 사용할 수 있습니다. 다음은 패턴 앞에 3 자, 실제 패턴에 이어 5 자 뒤에 인쇄합니다.

echo hey there how are you |perl -lne 'print "$1$2$3" if /(.{3})(there)(.{5})/'
ey there how

문자 대신 단어에 적용 할 수도 있습니다. 다음에 실제 일치하는 문자열 앞에 한 단어를 인쇄합니다.

echo hey there how are you |perl -lne 'print $1 if /(\w+) there/'
hey

다음은 패턴 뒤에 한 단어를 인쇄합니다.

echo hey there how are you |perl -lne 'print $2 if /(\w+) there (\w+)/'
how

다음은 패턴 앞에 하나의 단어를 인쇄 한 다음 패턴 뒤에 실제 단어와 한 단어를 인쇄합니다.

echo hey there how are you |perl -lne 'print "$1$2$3" if /(\w+)( there )(\w+)/'
hey there how

0

regexp grep을 사용하여 강조 표시를 위해 두 번째 grep을 찾을 수 있습니다.

echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}' | grep string

23_string_and

여기에 이미지 설명을 입력하십시오


0

나는이 암호 명령 수정자를 쉽게 기억하지 못하므로 최고의 대답을 가져 와서 ~/.bashrc파일 의 함수로 바꿨습니다 .


cgrep() {
    # For files that are arrays 10's of thousands of characters print.
    # Use cpgrep to print 30 characters before and after search patttern.
    if [ $# -eq 2 ] ; then
        # Format was 'cgrep "search string" /path/to/filename'
        grep -o -P ".{0,30}$1.{0,30}" "$2"
    else
        # Format was 'cat /path/to/filename | cgrep "search string"
        grep -o -P ".{0,30}$1.{0,30}"
    fi
} # cgrep()

실제 모습은 다음과 같습니다.

$ ll /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

-rw-r--r-- 1 rick rick 25780 Jul  3 19:05 /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

$ cat /tmp/rick/scp.Mf7UdS/Mf7UdS.Source | cgrep "Link to iconic"

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

$ cgrep "Link to iconic" /tmp/rick/scp.Mf7UdS/Mf7UdS.Source

1:43:30.3540244000 /mnt/e/bin/Link to iconic S -rwxrwxrwx 777 rick 1000 ri

문제의 파일은 하나의 연속 25K 라인이며 regular을 사용하여 찾고있는 것을 찾는 것은 희망이 없습니다 grep.

cgrep이 병렬 grep메소드를 호출 할 수있는 두 가지 다른 방법에 주목하십시오 .

"$ 2"가 4 줄의 코드를 저장하도록 설정된 경우에만 전달되는 함수를 생성하는 "niftier"방법이 있습니다. 그래도 편리하지는 않습니다. 같은 것 ${parm2} $parm2. 그것을 찾으면 기능 과이 답변을 수정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.