다른 파일의 열을 교차 검사하고 누락된 값을 인쇄하는 방법은 무엇입니까?

다른 파일의 열을 교차 검사하고 누락된 값을 인쇄하는 방법은 무엇입니까?

다음과 같은 파일이 있습니다. 12개의 열과 3244343개의 행이 있습니다. 이 파일의 이름을 1로 지정합니다.

variant_id  gene_id tss_distance    ma_samples  ma_count    maf pval_nominal    slope   slope_se    pval_nominal_threshold  min_pval_nominal    pval_beta
chr10_100000235_C_T_b38 ENSG00000227232.5   35211   73  74  0.061157    1.69779e-08 0.510322    0.0890939   0.0006160191.01823e-08  1.17701e-05
chr10_100002628_A_C_b38 ENSG00000227232.5   635545  126 130 0.107438    1.01823e-08 0.405406    0.0696647   0.0006160191.01823e-08  1.17701e-05
chr1_666028_G_A_b38 ENSG00000227232.5   636475  111 115 0.0950413   2.78462e-08 0.411513    0.0729864   0.0006160191.01823e-08  1.17701e-0

아래와 같이 7개의 헤더와 1633293줄의 다른 파일이 있습니다. 파일 2입니다.

"variant_id" "hg38_chr" "hg38_pos" "ref_allele" "alt_allele" "hg19_chr" "hg19_pos"
"chr10_100000235_C_T_b38" "chr10" "100000235" "C" "T" "chr10" 101759992
"chr10_100002628_A_C_b38" "chr10" "100002628" "A" "C" "chr10" 101762385
"chr10_100004827_A_C_b38" "chr10" "100004827" "A" "C" "chr10" 101764584
"chr10_100005358_G_C_b38" "chr10" "100005358" "G" "C" "chr10" 101765115

나는 variant_id칼럼에만 관심이 있다. 이는 두 파일의 첫 번째 열입니다.

variant_id이 두 열을 비교하여 첫 번째 열의 값만 인쇄하는 방법두 번째 파일에서 찾을 수 없습니다. 위 예의 경우 출력은 다음과 같아야 합니다.

chr1_666028_G_A_b38 

첫 번째 파일에서는 발견되지만 두 번째 파일에서는 발견되지 않기 때문입니다.

두 번째 파일의 모든 값은 variant_id첫 번째 파일에도 있습니다. 하지만 첫 번째 파일에는 두 번째 파일에는 없는 추가 ID가 있으며 이러한 ID를 식별하고 싶습니다.

답변1

시스템이 지원하는 경우프로세스 교체, 플래그(일치하지 않는 행 표시) 및 플래그(파일에서 패턴 읽기) grep와 함께 사용할 수 있습니다 . 여기서 "file"은 파일의 첫 번째 필드만 인쇄하는 명령입니다. 예를 들어:-v-f

$ grep -vf <(awk '{print $1}' file2) file1
variant_id  gene_id tss_distance    ma_samples  ma_count    maf pval_nominal    slope   slope_se    pval_nominal_threshold  min_pval_nominal    pval_beta
"chr1_666028_G_A_b38"   ENSG00000227232.5   636475  111 115 0.0950413   2.78462e-08 0.411513    0.0729864   0.0006160191.01823e-08  1.17701e-0

이것이 옵션이 아닌 경우 첫 번째 필드를 파일로 인쇄하고 다음을 사용할 수 있습니다.

$ awk '{print $1}' file2 > file2.names
$ grep -vf file2.names file1
variant_id  gene_id tss_distance    ma_samples  ma_count    maf pval_nominal    slope   slope_se    pval_nominal_threshold  min_pval_nominal    pval_beta
"chr1_666028_G_A_b38"   ENSG00000227232.5   636475  111 115 0.0950413   2.78462e-08 0.411513    0.0729864   0.0006160191.01823e-08  1.17701e-0

또는 모든 변형 ID를 file2에 저장할 만큼 RAM이 충분하다고 가정하면(매우 오래된 하드웨어를 사용하지 않는 한 이렇게 해야 함) awk이를 사용하여 파일의 첫 번째 필드를 모두 다른 파일에 저장할 수 있습니다.

$ awk 'NR == FNR{a[$1]++;next}; !($1 in a)' file2 file1
variant_id  gene_id tss_distance    ma_samples  ma_count    maf pval_nominal    slope   slope_se    pval_nominal_threshold  min_pval_nominal    pval_beta
"chr1_666028_G_A_b38"   ENSG00000227232.5   636475  111 115 0.0950413   2.78462e-08 0.411513    0.0729864   0.0006160191.01823e-08  1.17701e-0

답변2

먼저 두 파일을 모두 정렬합니다(물론 헤더는 제외). 그런 다음 awk또는 를 사용하여 cut첫 번째 열(헤더 제외)을 선택하고 절차적 대체를 사용하여 다음에 없는 열을 선택합니다 comm.file1file2

comm -23 <(awk 'NR>1 {print $1;}' file1) <(awk 'NR >1 {print $1;}' file2)

프로세스 대체 [1]의 명령을 스크립트로 리팩터링하여 약간 단순화할 수 있습니다 col1-nh(예: "첫 번째 열, 제목 없음").

#! /bin/bash

file=$1

awk 'NR>1 {print $1;}' $file

명령은 다음과 같습니다:

comm -23 <(col1-nh file1) <(col1-nh file2)

다시 말하지만, 이는 파일 본문이 다음과 같다고 가정합니다.정렬됨. 그러나 이것은 이고 O(N logN)둘 다입니다 col1-nh. comm여기서 O(N)N은 줄 수이므로 언급한 크기의 파일을 문제 없이 처리할 수 있어야 합니다. 제안된 각 솔루션에 소요되는 시간을 확실히 측정해야 합니다.


[1] @terdon이 호출 NR>1에서 이를 사용하도록 제안했지만 더 이상 필요하지 않으며 명령 자체가 충분히 간단하다고 생각할 수도 있습니다.awksed

관련 정보