특수한 출력이 있는 파일에서 정규식 패턴을 반복적으로 검색하는 데 도움이 됩니다.

특수한 출력이 있는 파일에서 정규식 패턴을 반복적으로 검색하는 데 도움이 됩니다.

내 문제는 다음이 필요하다는 것입니다.

  1. regex_pattern주어진 루트 디렉터리의 모든 파일에서 일치하는 모든 줄 찾기 (심층 검색)
  2. 일치하는 각 줄에 대해 다음을 출력합니다.
    • 파일 이름
    • 일치하는 항목이 포함된 줄 번호
    • 행 내용
    • 정규식 패턴
  3. 위의 데이터를 Excel로 가져옵니다. 따라서 CSV 또는 구분된 출력 형식을 염두에 두세요.

이 작업을 수행하는 가장 쉬운 방법은 무엇입니까?

이에 대해 생각했다는 것을 보여주기 위해, 정규화된 단일 파일 이름과 정규식 패턴을 입력으로 사용하고 다음과 같은 대략적인 Perl을 사용하여 행을 처리하는 Perl 스크립트를 작성하겠습니다(아직 시도하지 않았지만 이 내용은 내 첫 번째 시도입니다):

while (<FILE>) {
  $line_number++;

  if ($_ =~ m/regex_pattern/) {
    # output: file_name\tline_number\tregex_pattern\t$_
    # ignore escaping issues for the time being
  }
}

재귀 검색을 통해 각 디렉토리의 내용을 이 Perl 스크립트에 전달하는 방법을 아직도 잘 모르겠습니다. Perl로 검색할 수도 있지만 Unix/Linux에서 이 작업을 수행하는 좋은 방법이 있을 것이라고 확신합니다.

나는 Perl과 결혼하지 않았습니다. 표준 Unix/Linux 도구를 함께 연결할 수 있는 방법이 있다면 좋을 것입니다. 그렇지 않다면 Perl의 구문에 어느 정도 익숙하기 때문에 Perl을 사용하는 것을 선호합니다.

답변1

이 같은?

find /search/root -type f -exec awk 'BEGIN{pattern="regex_pattern"} $0 ~ pattern {printf "%s,%s,%s,%s\n",FILENAME,FNR,$0,pattern}'  {} +

답변2

start cmd:> find . -type f -name 'search*' -exec awk -v regex=foo \
cont. cmd:>   '$0 ~ regex {print FILENAME,FNR,regex,$0 }' {} +
./searchfile1 1 foo a_foo_b
./searchfile2 1 foo foo

답변3

Perl에서는 다음을 사용하십시오.빈 파일 핸들명령줄 인수에 대해 작동합니다.

#!/usr/bin/perl -n
$, = "\t";  # separator added between arguments to print
while (<>) {
  if (/regex_pattern/) {
    # $ARGV contains the current file name, $. contains the current line number,
    # $_ contains the current line including its terminating newline
    print $ARGV, $., 'regex_pattern', $_;
  }
  $. = 0 if eof;  # reset the line number between files
}

Perl 스크립트에 파일 이름을 전달하려면 ksh93 또는 bash ≥4 또는 zsh에서 다음을 사용할 수 있습니다.**무늬하위 디렉터리를 재귀적으로 탐색합니다. ksh에서는 먼저 set -o globstar. Bash에서는 shopt -s globstar.

shopt -s globstar
name_of_perl_script **/*

쉘이 그렇지 않거나 **"명령줄이 너무 깁니다" 오류가 발생하는 경우 를 사용할 수 있습니다 find.

find . -type f -exec name_of_perl_script {} +

보다 전문화된 도구를 결합하여 이를 수행할 수도 있습니다. 파일에서 패턴을 검색하는 grep을 이미 알고 있을 수도 있습니다. 이 -n옵션을 사용하면 일치하는 각 줄의 번호가 인쇄됩니다. 파일 이름으로 전달하는 것은 파일 이름도 인쇄되도록 하는 방법 /dev/null입니다 grep(명령줄에 단일 파일이 있는 경우에는 이 작업을 수행하지 않습니다).

grep -n 'regex_pattern' **/*

누락된 것은 필요한 경우 구분 기호를 변경하고( grep파일 이름, 줄 번호 및 줄 내용 사이에 삽입) 정규식을 올바른 위치에 삽입하는 것입니다. :이 간단한 교체는 완벽하게 작동합니다 sed. 정규식을 올바르게 인용했는지 확인하세요.

find . -type f -exec grep -n 'regex_pattern' {} + |
sed 's/^\([^:]*\)\([^:]*\)/\1\t\2\tregex_pattern\t/'

관련 정보