grep 컨텍스트를 N자로 제한

grep 컨텍스트를 N자로 제한

수천 자보다 긴 줄이 포함된 일부 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 스타일 정규식 사용
  • 정규식은 $N0을 문자와 일치시킨 다음 0을 문자 foo와 일치시키는 것을 의미합니다.$N

GNU가 없는 경우 grep:

find . -type f -exec \
    perl -nle '
        BEGIN{$N=10}
        print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
    ' {} \;

설명하다:

우리는 더 이상 grepGNU 에 의존할 수 없기 때문에 파일에 대한 재귀 검색을 grep사용합니다 ( GNU의 작업 ). 발견된 각 파일에 대해 Perl 코드 조각을 실행합니다.find-rgrep

Perl 스위치:

  • -n파일을 한 줄씩 읽기
  • -l각 줄 끝의 개행 문자를 제거하고 인쇄할 때 다시 넣습니다.
  • -e다음 문자열을 코드로 고려하십시오.

Perl 코드 조각은 기본적으로 grep변수를 $N원하는 수의 컨텍스트 문자로 설정하는 것과 기본적으로 동일합니다. 즉, BEGIN{}파일의 각 줄에 대해 한 번 실행되는 것이 아니라 실행 시작 시 한 번만 실행됩니다.

정규식 대체가 유효한 경우 각 줄에서 실행되는 명령문은 해당 줄을 인쇄합니다.

정규식:

  • line () 1 의 시작 부분에서 오래된 항목과 일치하는 것을 지연하고 ^.*?, 이 예에서와 .{0,$N}동일한 경우, 또 다른 경우 , 마지막으로 line () 의 끝까지 오래된 항목과의 일치를 지연합니다 .grepfoo.{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자만 있어야 합니다.

관련 정보