두 파일의 첫 번째 열을 기준으로 일치하는 줄을 제외합니다.

두 파일의 첫 번째 열을 기준으로 일치하는 줄을 제외합니다.

두 개의 탭으로 구분된 텍스트 파일이 있습니다. 더 큰 기본 파일인 파일 1에는 여러 열이 있는 반면, 파일 2는 제한된 행의 처음 두 열만 파일 2와 공유하는 더 작은 파일입니다.

File 3을 출력으로 갖고 두 파일의 첫 번째 열 사이에 일치하는 줄을 제외하고 File 1의 다른 모든 열을 인쇄하고 싶습니다.

시도했지만 grep -vf작동하지 않는 것 같습니다. 또한 두 열 모두에 대한 일치 항목이 필요합니다.

파일 1:

BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P
1650048 1   rs112618790 C   T   T   12387   1.00246 0.0877604   0.0279678   0.977688
1856473 1   rs6684487   G   A   A   12387   1.02222 0.0836593   0.262689    0.79279

파일 2:

BP  CHR
1650048 1
1650483 1

출력(파일 3):

BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P
1856473 1   rs6684487   G   A   A   12387   1.02222 0.0836593   0.262689    0.79279

답변1

파일이 첫 번째 필드를 기준으로 정렬되었다고 가정하면 다음 명령을 사용하여 첫 번째 필드가 두 번째 파일에 나타나지 않는 첫 번째 파일의 모든 레코드를 추출할 수 있습니다.

$ join -v 1 file1 file2
1856473 1 rs6684487 G A A 12387 1.02222 0.0836593 0.262689 0.79279

탭 구분 기호 및 제목을 유지하려면 다음을 수행하십시오.

$ head -n 1 file1; join -t $'\t' -v 1 file1 file2
BP      CHR     SNP     REF     ALT     A1      OBS_CT  OR      LOG(OR)_SE      Z_STAT  P
1856473 1       rs6684487       G       A       A       12387   1.02222 0.0836593       0.262689        0.79279

일치를 위해 첫 번째 및 두 번째 필드를 모두 사용하려면 두 파일의 이러한 필드를 기반으로 결합된 새 첫 번째 필드를 만들고 해당 필드에 조인한 다음 임시 조인 필드를 제거합니다. 이것은 기본적으로 다음과 같은 것을 구현합니다.장식-정렬-장식 취소, 그러나 정렬을 위해 관계형 JOIN 연산을 사용합니다.

다음 코드에서는 쉘을 사용할 수 있다고 가정합니다 <(...).

$ head -n 1 file1; join -t $'\t' -v 1 <( awk -F '\t' 'BEGIN { OFS=FS } { print $1 "_" $2, $0 }' file1 ) <( awk -F '\t' 'BEGIN { OFS=FS } { print $1 "_" $2, $0 }' file2 ) | cut -f 2-
BP      CHR     SNP     REF     ALT     A1      OBS_CT  OR      LOG(OR)_SE      Z_STAT  P
1856473 1       rs6684487       G       A       A       12387   1.02222 0.0836593       0.262689        0.79279

또는 도우미 셸 기능을 사용하여 명령을 더 쉽게 읽을 수 있도록 합니다.

$ decorate () {  awk -F '\t' 'BEGIN { OFS=FS } { print $1 "_" $2, $0 }' "$1"; }
$ head -n 1 file1; join -t $'\t' -v 1 <( decorate file1 ) <( decorate file2 ) | cut -f 2-
BP      CHR     SNP     REF     ALT     A1      OBS_CT  OR      LOG(OR)_SE      Z_STAT  P
1856473 1       rs6684487       G       A       A       12387   1.02222 0.0836593       0.262689        0.79279

답변2

한 가지 옵션은 다음을 사용하는 것입니다 awk.

awk '
    # set the input Field Seperator to a Tab
    BEGIN  { FS="\t" }
 
    # store column#1,column#2 of file2 into associated array bp_file2
    NR==FNR{ bp_file2[$1, $2]; next }

    # do not print lines of file1 if column#1 was in the array
                      # with FNR==1 we are printing the first header line too
    !(($1, $2) in bp_file2) || FNR==1

' file2 file1

답변3

Python 솔루션. 아마도 다른 것보다 길지만 더 읽기 쉬울 것입니다(저만요?).

file1 = '1'
file2 = '2'
separator = '\t'

list2=[]

# first building up a list of IDs from file2:
with open(file2) as f:
    for line in f:
        if line[0].isdigit(): # only process lines which start with number
            list2.append(line.split(separator)[0])

# then go through file1 and check IDs from the previously built list 
with open(file1) as f:
    print(f.readline(), end='') # printing out header
    for line in f:
        if not line.split(separator)[0] in list2:
            # print out line which IDs are not in list2 (not in file2)
            print(line, end='')

다음과 같이 실행하세요.

python3 file.py > 3

답변4

awk 'BEGIN{print "BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P"}NR==FNR{a[$1];next}!($1 in a){print $0}' file2 file1

산출

BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P
1856473 1   rs6684487   G   A   A   12387   1.02222 0.0836593   0.262689    0.79279

파이썬

#!/usr/bin/python
import re
f1=open('/home/praveen/file1','r')
f2=open('/home/praveen/file2','r')
f3=open('/home/praveen/file3','w')
f1.readline()
f2.readline()

for i in f2:
    i_split=i.split(' ')
#    print i.split(' ')
    for j in f1:
        j_split=j.split(' ')
        if (i_split[0] != j_split[0]):
            str_append="BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P"
            appnddata="{0}\n{1}\n".format(str_append,j.strip())
            f3.write(appnddata)

산출

BP  CHR SNP REF ALT A1  OBS_CT  OR  LOG(OR)_SE  Z_STAT  P
1856473 1   rs6684487   G   A   A   12387   1.02222 0.0836593   0.262689    0.79279

관련 정보