여러 일치 항목에 대해 일치하는 파일 이름을 한 번만 인쇄하는 방법(파일 이름만 인쇄하는 것이 아님)

여러 일치 항목에 대해 일치하는 파일 이름을 한 번만 인쇄하는 방법(파일 이름만 인쇄하는 것이 아님)

동시에 여러 로그의 콘텐츠를 스크랩하고 있습니다.grep -Er

하지만 파일 접두어를 한 번만 일치시키고 싶습니다.

내가 달성하려는 것은 다음과 같습니다 ls -lr(파일을 한 번 일치시킨 다음 해당 파일마다 일치하는 모든 줄)

설명서에서 이 옵션을 찾지 못했습니다.

grep만으로 할 수 있나요? 어떻게?

답변1

grep내가 아는 한 구현이 없습니다. -r표준 옵션 자체는 아닙니다. find파일을 찾아서 perl일치시키고 파일 경로를 보고 하는 함수를 스크립트나 함수에서 쉽게 구현할 수 있습니다 .

rPgrep() {
  local pattern="$1"
  shift
  find -- "$@" -type f -print0 |
    perl -C -0se '
      @ARGV = <STDIN>;
      $ /= "\n";
      while (<<>>) {
        if (/$pattern/) {
          unless ($header_already_printed) {
            print "\n" if defined $header_already_printed;
            print "$ARGV:\n";
            $header_already_printed = 1;
          }
          print;
        }
        $header_already_printed &&= 0 if eof;
      }' -- -pattern="$pattern"
}

그런 다음:

rPgrep pattern some/dir some/other/dir or/regular/file

일반 파일에 대한 심볼릭 링크도 보려면 (GNU 가정) -type로 바꾸십시오. 또는 GNU (대신)와 같은 디렉토리 트리를 내려갈 때 심볼릭 링크를 따라가는 옵션을 추가하세요.-xtypefind-Lfindgrep -R-r

보너스로 제한된 정규 표현식 대신 Perl 정규 표현식( grep지원되는 일부 정규 표현식과 유사)을 얻을 수 있습니다.-P연장하다당신이 얻는 것 -E.

대소문자를 구분하지 않는 일치( -i) 또는단어일치( -w), 역방향 일치( -v) 또는 전체 행 일치( -x)는 정규식 구문( (?i), \b, (?!...), ^...\z)을 사용하여 수행할 수 있지만 다른 grep옵션( -n, -l또는 // / -F와 같은 일부 비표준 확장 ) 의 경우 ... Perl 코드를 수정해야 합니다.-o-A-B-C

다음을 수행할 수도 있습니다.

find . -type f -exec grep -q pattern {} ';' \
               -exec printf '\n%s:\n' {} ';' \
               -exec grep pattern {} ';'

그러나 이는 파일당 최대 3개의 명령을 실행한다는 의미이므로 매우 비효율적입니다.

GNU의 경우 find이는 -exec printf '\n%s:\n' {} ';'로 대체될 수 있습니다 -printf '\n%p:\n'.

관련 정보