각 줄이 고유 식별자로 시작하는 파일이 있습니다. 예를 들면 다음과 같습니다.
$ 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
$