grep 패턴과 파일 쌍

grep 패턴과 파일 쌍

다른 txt 파일 목록에서 검색하려는 패턴 목록이 포함된 파일(search.patterns)이 있습니다.

검색 모드

home
dog 
cat

파일 1.txt

home 3
tiger 4
lion 1

파일 2.txt

dolphin 6
jaguar 3
dog 1

파일 3.txt

donkey 3
cat 4
horse 1

그래서 file1에서 패턴 파일의 첫 번째 줄, file2에서 두 번째 줄, file3에서 세 번째 줄을 검색하고 싶습니다.

산출:

home 3
dog 1
cat 4

나는 다음과 같은 코드를 작성했습니다.

for f in *.txt;
    do 
    while IFS= read -r LINE; 
        do grep -f "$LINE" "$f" > "$f.out"
    done < search.patterns
done

하지만 출력 파일이 비어 있습니다.

어떤 도움이라도 대단히 감사하겠습니다. 감사합니다.

답변1

GNU awk( )를 사용하면 입력 파일이 변경될 때마다 규칙을 gawk사용하여 새 패턴을 읽을 수 있습니다 .BEGINFILE

$ gawk 'BEGINFILE{getline pat < "search.patterns"} $0 ~ pat' file\ {1..3}.txt
home 3
dog 1
cat 4

getline예를 들어 새로운 모드가 반환되는지 실제로 확인해야 합니다.

gawk '
  BEGINFILE {
    if((getline pat < "search.patterns") <= 0) {
      print "Error reading pattern" > "/dev/stderr"
      exit 1
    }
  } 
  $0 ~ pat
' file\ {1..3}.txt

참고로 awk패턴은확장하다grepwith 옵션 -E이 지원하는 표현식 과 유사한 정규 표현식입니다 .

첫 번째 파일로 전달 하고 적절하게 사용하여 패턴을 인덱스 배열로 읽거나 배열에서 다음 패턴을 찾는 방식으로 awk비GNU에서도 동일한 효과를 얻을 수 있습니다.search.patternsNRFNR

답변2

사용 bash:

#!/bin/bash

files=( 'file 1.txt' 'file 2.txt' 'file 3.txt' )

while IFS= read -r pattern; do
    grep -e "$pattern" "${files[0]}"
    files=( "${files[@]:1}" )
done <search.patterns

테스트해보세요:

$ bash script.sh
home 3
dog 1
cat 4

스크립트는 관련 파일 이름을 files배열에 저장한 다음 search.patterns파일에서 패턴을 읽습니다. 각 패턴에 대해 files목록의 첫 번째 파일이 쿼리됩니다. 그런 다음 처리된 파일은 목록에서 제거됩니다 files(결과적으로 목록의 새로운 첫 번째 파일 이름이 생성됨).

패턴 수가 의 파일 수를 초과하면 files오류가 발생합니다 grep.

답변3

paste이 패턴을 사용하여 파일을 일치시킬 수 있습니다 .

paste <(printf "%s\n" *.txt) search.patterns | while IFS=$'\t' read -r file pattern; do
    grep -- "$pattern" "$file"
done

파일 이름에 탭 문자가 포함되어 있지 않다고 가정합니다.

관련 정보