파일 B의 용어를 사용하여 파일 A를 검색하고 파일 B의 검색 용어를 기반으로 개별 TXT 파일에 출력을 저장합니다.

파일 B의 용어를 사용하여 파일 A를 검색하고 파일 B의 검색 용어를 기반으로 개별 TXT 파일에 출력을 저장합니다.

FILE-A에는 100,000개의 행이 있습니다. FILE-B는 50개의 검색어입니다. FILE-B(CSV 또는 TXT)의 다양한 용어를 사용하여 FILE-A(CSV 또는 TXT) 검색을 완료하고 - 여기에 핵심이 있습니다. - FILE-B 용어 검색을 기반으로 별도의 TXT 파일에 결과를 저장하고 싶습니다. 의.

예:

파일-A

123
45678
1239870
2349878
39742366876
41967849
789
910
2378
6723

파일-B

1
2
23
78

결과 = "1.txt"에는 FILE-A에서 일치하는 모든 줄이 포함되고, "2.txt"에는 FILE-A에서 일치하는 모든 줄이 포함되며, "23.txt", "78.txt" 등이 포함됩니다. 따라서 FILE-B에 50개의 검색어가 있는 경우 FILE-A에 해당 용어와 일치하는 파일이 하나 이상 있다고 가정하면 검색어 이름을 딴 50개의 TXT 파일이 생성됩니다.

FILE-A에서 찾은 FILE-B의 모든 검색어를 하나의 "output.txt" 중간에 넣는 "fgrep -f FILE-B.txt FILE-A.csv >> output.txt"를 사용하여 검색합니다. 대신 별도의 텍스트 파일로 분리하고 싶습니다.

답변1

Grep+Xargs

xargs -d '\n' sh -c '
    for term; do grep "$term" fileA > "$term.txt"; done
' xargs-sh < fileB

으로 개선되었습니다카스.

Grep+ 쉘

일반적으로 말하면셸을 사용하여 파일을 반복하는 것은 나쁜 습관입니다., 그러나 여기서는 fileB그것보다 훨씬 작 fileA으므로 성능에 큰 영향을 미치지 않습니다.

while IFS= read -r term; do
    grep "$term" fileA > "$term.txt"
done < fileB

awk 'NR==FNR{pat[$0];next}{for(term in pat){if($0~term){print>term}}}' fileB fileA
  • NR==FNR{pat[$0];next}인수로 제공된 첫 번째 파일을 읽고 각 줄을 배열에 넣습니다 pat.
  • {for(term in pat){if($0~term){print>term}}}설명이 필요합니다. term배열의 각 요소에 대해 현재 줄이 해당 용어와 일치하는지 테스트하고 일치하는 경우 적절한 이름의 파일에 인쇄합니다.

모든 Awk가 동시에 여러 파일을 열 수 있는 것은 아닙니다. 이 문제를 해결하는 한 가지 방법은 제안하는 것입니다.에드 모튼close, 명령문을 사용 하고 추가 연산자를 사용하십시오.

awk 'NR==FNR{pat[$0];next}{for(term in pat){if($0~term){print>>term;close(term)}}}' fileB fileA

답변2

grep -F이는 매우 빠른 첫 번째 패스를 사용하여 FILE-B의 라인(아마도 FILE-A의 원래 100,000 라인보다 훨씬 적음)과 일치하는 FILE-A의 라인을 출력하기 때문에 작동합니다. awk 스크립트는 FILE-A에 비교할 행이 많지 않으며 FILE-A를 읽을 때 FILE-B의 행을 반복하는 대신 FILE-B를 읽을 때 해당 행을 반복할 수 있으므로 FILE만 수행할 수 있습니다. - FILE-B의 각 라인에 대해 한 번에 1개의 출력 파일을 열기/닫는 대신 B의 각 라인에 대해 한 번에 1개의 출력 파일 열기/닫기 * 일치하는 FILE-A의 각 라인에 대해 "너무 많은 열기" 가능성을 방지합니다. 파일 "실수.

$ cat tst.sh
#!/usr/bin/env bash

grep -F -f 'FILE-B' 'FILE-A' |
awk '
    NR==FNR{ lines[++numLines]=$0; next }
    {
        close(out)
        out = $0 ".txt"
        for (i=1; i<=numLines; i++) {
            line = lines[i]
            if (index(line,$0)) {
                print line > out
            }
        }
    }
' - 'FILE-B'

$ ./tst.sh

$ head -100 *.txt
==> 1.txt <==
123
1239870
41967849
910

==> 2.txt <==
123
1239870
2349878
39742366876
2378
6723

==> 23.txt <==
123
1239870
2349878
39742366876
2378
6723

==> 78.txt <==
45678
2349878
41967849
789
2378

관련 정보