![grep 컨텍스트를 N자로 제한](https://linux55.com/image/58075/grep%20%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%A5%BC%20N%EC%9E%90%EB%A1%9C%20%EC%A0%9C%ED%95%9C.png)
수천 자보다 긴 줄이 포함된 일부 JSON 파일을 파악해야 합니다.일치하는 항목의 왼쪽과 오른쪽에 최대 N자까지 컨텍스트를 표시하도록 grep을 제한하려면 어떻게 해야 합니까?일반적인 Linux 패키지에서 사용할 수 있는 한 grep 이외의 모든 도구가 가능합니다.
이는 예제 출력입니다.가상의 grep 스위치 Ф:
$ grep -r foo *
hello.txt: Once upon a time a big foo came out of the woods.
$ grep -Ф 10 -r foo *
hello.txt: ime a big foo came of t
답변1
이것을 사용해 보세요:
grep -r -E -o ".{0,10}wantedText.{0,10}" *
-이자형확장 정규 표현식을 사용하라고 알려줍니다.
-영형일치하는 항목만 인쇄하고 싶다고 말합니다.
-아르 자형grep이 폴더에서 재귀적으로 결과를 찾는 중입니다.
정규식:
{0,10}인쇄할 임의의 문자 수를 알려줍니다.
.모든 문자를 나타냅니다(문자 자체는 중요하지 않으며 숫자만 중요함).
편집하다:아 그렇군요. Joseph이 추천한 솔루션이 저와 거의 동일하네요. :D
답변2
cut
표준 출력을 파이프하려면 플래그를 사용하십시오 -b
. grep 출력에 한 줄에 1~400바이트만 포함하도록 지시할 수 있습니다.
grep "foobar" * | cut -b 1-400
답변3
GNU 사용 grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
설명하다:
-o
=> 일치하는 내용만 인쇄하세요.-P
=> Perl 스타일 정규식 사용- 정규식은
$N
0을 문자와 일치시킨 다음 0을 문자foo
와 일치시키는 것을 의미합니다.$N
GNU가 없는 경우 grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
설명하다:
우리는 더 이상 grep
GNU 에 의존할 수 없기 때문에 파일에 대한 재귀 검색을 grep
사용합니다 ( GNU의 작업 ). 발견된 각 파일에 대해 Perl 코드 조각을 실행합니다.find
-r
grep
Perl 스위치:
-n
파일을 한 줄씩 읽기-l
각 줄 끝의 개행 문자를 제거하고 인쇄할 때 다시 넣습니다.-e
다음 문자열을 코드로 고려하십시오.
Perl 코드 조각은 기본적으로 grep
변수를 $N
원하는 수의 컨텍스트 문자로 설정하는 것과 기본적으로 동일합니다. 즉, BEGIN{}
파일의 각 줄에 대해 한 번 실행되는 것이 아니라 실행 시작 시 한 번만 실행됩니다.
정규식 대체가 유효한 경우 각 줄에서 실행되는 명령문은 해당 줄을 인쇄합니다.
정규식:
- line () 1 의 시작 부분에서 오래된 항목과 일치하는 것을 지연하고
^.*?
, 이 예에서와.{0,$N}
동일한 경우, 또 다른 경우 , 마지막으로 line () 의 끝까지 오래된 항목과의 일치를 지연합니다 .grep
foo
.{0,$N}
.*?$
- 는 현재 읽고 있는 파일의 이름을 보유하는 마법 변수 로 대체됩니다
$ARGV:$1
. 괄호가 일치하는 것은 이 경우의 컨텍스트입니다.$ARGV
$1
foo
욕심 많은 일치는 일치 실패 없이 이전 문자를 모두 먹어치우기 때문에 (.{0,$N}
0개의 일치 항목이 허용되기 때문에) 양쪽 끝에서 지연 일치가 필요합니다.
1 즉, 전체 일치가 실패하지 않는 한 아무것도 일치하지 않는 것이 가장 좋습니다. 즉, 가능한 한 적은 수의 문자를 일치시키십시오.
답변4
출처:http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserves-color/ 그리고 https://stackoverflow.com/a/39029954/1150462
".{0,10}<original pattern>.{0,10}"
강조 색상이 종종 엉망이라는 점을 제외하면 제안된 접근 방식 은 매우 좋습니다. 비슷한 출력으로 스크립트를 만들었지만 색상도 유지되었습니다.
#!/bin/bash
# Usage:
# grepl PATTERN [FILE]
# how many characters around the searching keyword should be shown?
context_length=10
# What is the length of the control character for the color before and after the matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))
grep -E --color=always "$1" $2 | grep --color=none -oE ".{0,$(($control_length_before + $context_length))}$1.{0,$(($control_length_after + $context_length))}"
스크립트가 로 저장되었다고 가정 grepl
하면 grepl pattern file_with_long_lines
일치하는 줄이 표시되어야 하지만 일치 문자열 주위에는 10자만 있어야 합니다.