반복되는 패턴이 있는 목록을 기반으로 텍스트 파일에서 여러 줄을 추출합니다.

반복되는 패턴이 있는 목록을 기반으로 텍스트 파일에서 여러 줄을 추출합니다.

각 줄이 고유 식별자로 시작하는 파일이 있습니다. 예를 들면 다음과 같습니다.

$ cat source.txt
aaa text
bbb text
ccc text
ddd text
eee text

-f 옵션과 함께 fgrep을 사용하여 다른 파일("list.txt"라고 함)에 나열된 식별자가 포함된 줄을 새 파일에 저장해 보았습니다.

fgrep -f list.txt source.txt > new.txt

문제는 "list.txt"의 일부 식별자가 중복된다는 것입니다. 예:

$ cat list.txt
aaa
ccc
ccc
ccc
eee
eee

여기서 grep은 반복되는 각 식별자를 한 번만 나열된 것처럼 처리하여 다음과 같은 결과를 제공합니다.

$ cat new.txt
aaa text
ccc text
eee text

대신, 반복된 식별자가 포함된 행을 해당 식별자가 반복되는 정확한 횟수로 list.file에 저장하고 싶습니다. 이 경우 더 나은 최종 결과는 다음과 같습니다.

$ cat new.txt
aaa text
ccc text
ccc text
ccc text
eee text
eee text

grep이 중복 식별자를 한 번만 나열된 것처럼 처리하지 않도록 강제하는 간단한 방법이 있습니까? 또는 awk를 사용하는 등 grep 없이 원하는 결과를 얻을 수 있는 다른 방법이 있습니까?


문제를 더 잘 시각화하기 위해 source.txt의 실제 줄은 다음과 같습니다.

head -n 1 source.txt | cat -T
GCF_000005825.2_WP_003320558.1 MULTISPECIES: IS21-like element helper ATPase IstB [Bacillaceae]^IMNEQIQAYAKRLKLSWIRENFNQIEAETNEEYLLKLFEKEVQNREERKVNLLLSQAQLPKTGSTPFQWEHIQIPQGIERTAVINGDFIKERENLILYGGVGTGKTYLATLLSLNAIHRFGSQVKFYTVAGLVNKLIEANQKNTLPKLMKQIEKLDLLILDELGYIPLNKEGAELLFQVISMCYENRSIVITTNLQFGQWNHVFGDPILTEAVIDRLIHHSHLLVFKGDSFRYKESLLHQ

일치하는 식별자는 다음과 같습니다.

GCF_000005825.2_WP_003320558.1

답변1

이를 수행하는 한 가지 방법은 다음과 같습니다 awk( source.txt메모리 문제가 발생할 정도로 크지 않다고 가정).

$ awk 'NR==FNR{a[$1]=$0; next} $0 in a{print a[$0]}' source.txt list.txt
aaa text
ccc text
ccc text
ccc text
eee text
eee text
  • NR==FNR{a[$1]=$0; next}그러면 첫 번째 필드를 키로 하고 전체 입력 줄을 값으로 사용하여 배열을 만듭니다( source.txt이 경우 첫 번째 파일의 경우).
  • $0 in a{print a[$0]}list.txt파일을 처리할 때 각 라인이 배열의 키로 존재하는지 확인 a하고 해당 라인을 인쇄합니다.

다음은 메모리 측면에서 더 나은 성능을 발휘하는 수정된 솔루션입니다(행에 source.txt단일 공백으로 구분된 정확히 두 개의 필드가 있다고 가정).

awk 'NR==FNR{a[$1]=$2; next} $0 in a{print $0, a[$0]}'

전체 행 대신 두 번째 필드만 배열에 저장됩니다. 인쇄되면 키 앞에 붙습니다.

답변2

xargs무거운 짐을 싣는 또 다른 방법 .

$ grep -v "^$" list.txt | xargs -I{} grep "^{} " source.txt
aaa text
ccc text
ccc text
ccc text
eee text
eee text
$

관련 정보