다른 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
패턴은확장하다grep
with 옵션 -E
이 지원하는 표현식 과 유사한 정규 표현식입니다 .
첫 번째 파일로 전달 하고 적절하게 사용하여 패턴을 인덱스 배열로 읽거나 배열에서 다음 패턴을 찾는 방식으로 awk
비GNU에서도 동일한 효과를 얻을 수 있습니다.search.patterns
NR
FNR
답변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
파일 이름에 탭 문자가 포함되어 있지 않다고 가정합니다.