두 파일 사이의 교차점

두 파일 사이의 교차점

다음이 포함된 파일이 있습니다.단일 염기 다형성 데이터라고 불리며 snp.bed다음과 같습니다.

head snp.bed

    Chr17   214708483   214708484   Chr17:214708484
    Chr17   214708507   214708508   Chr17:214708508
    Chr17   214708573   214708574   Chr17:214708574

또한 다음과 같은 이름의 파일이 있습니다 intersect.bed.

head intersect.bed

    Chr17   214708483   214708484   Chr17:214708484 Chr17   214706266   214710783   gene50573
    Chr17   214708507   214708508   Chr17:214708508 Chr17   214706266   214710783   gene50573
    Chr17   214708587   214708588   Chr17:214708580 Chr17   214706266   214710783   gene50573

snp.bed각 행에 추가 열을 추가하여 수정된 버전을 인쇄하고 싶습니다 . 의 행이 snp.bed의 행의 처음 4개 열과 일치 intersect.bed하면 전체 행을 인쇄하고 snp.bed(유전자 이름)의 해당 행의 마지막 열에 인접하여 추가 열을 가져오고 싶습니다. intersect.bed또는 from 행이 snp.bedfrom 행과 일치하지 않는 경우 intersect.bed유전자 이름 대신 문자열 "NA"로 구성된 추가 열에 인접합니다.

이것이 내가 원하는 결과입니다:

head snp.matched.bed

    Chr17   214708483   214708484   Chr17:214708484   gene50573
    Chr17   214708507   214708508   Chr17:214708508   gene50573
    Chr17   214708573   214708574   Chr17:214708574   NA

어떻게 해야 하나요?

답변1

이 솔루션은 파일의 줄 시작 부분에 공백이 없다고 가정합니다. 이러한 공백이 있는 예제와 다른 점은 무엇입니까?

awk '
{
    str = $1$2$3$4; 
}
FNR == NR {
    arr[str] = $NF;
}
FNR != NR {
    gene_name = arr[str] ? arr[str] : "NA";
    print $0, gene_name;
}' intersect.bed snp.bed 

산출

Chr17   214708483   214708484   Chr17:214708484 gene50573
Chr17   214708507   214708508   Chr17:214708508 gene50573
Chr17   214708573   214708574   Chr17:214708574 NA

답변2

awk를 사용하는 솔루션은 다음과 같습니다.

$ awk -F '\t' 'BEGIN{while(getline line<"intersect.bed") {N=split(line,a,"\t"); seen[a[1]"\t"a[2]"\t"a[3]"\t"a[4]]=a[N];}} {if(seen[$0]) {name=seen[$0];} else{name="NA"}; print $0 "\t" name}' snp.bed
Chr17       214708483       214708484       Chr17:214708484 gene50573
Chr17       214708507       214708508       Chr17:214708508 gene50573
Chr17       214708573       214708574       Chr17:214708574 NA

두 개의 입력 파일에 대한 구분 기호로 단일 탭 문자를 가정합니다.

또한 "첫 번째 네 번째 열"을 "처음 네 열"로 해석했습니다.

답변3

개인적으로 이러한 작업에는 "실제" 프로그래밍 언어를 사용하는 것이 더 낫다고 생각합니다. 저는 Python을 좋아합니다. 그래서 여기에 여러분이 원하는 것을 수행하는 Python 스크립트가 있습니다(이는 여러분이 쉽게 이해하고 수정할 수 있도록 의도적으로 장황하게 작성되었습니다).

#!/usr/bin/env python2

# intersect.py

# Read data from the first file
snp_rows = []
with open("snp.bed", 'r') as snp_file:
    for row in snp_file:
        snp_rows.append(row.split())

# Read data from the second file
int_rows = []
with open("intersect.bed", 'r') as int_file:
    for row in int_file:
        int_rows.append(row.split())

# Compare data and compute results
results = []
for row in int_rows:
    if row[:4] in snp_rows:
        results.append(row[:4] + [row[-1]])
    else:
        results.append(row[:4] + ["NA"])

# Print the results
for row in results:
    print(' '.join(row))

파일에 저장한 후 다음을 실행합니다.

python2 intersect.py

재미삼아 표준 명령(단지 grep및 )을 사용하는 cutBash 솔루션은 다음과 같습니다.

while read row; do
    match="$(grep -F "${row}" intersect.bed)";
    if [[ -n "${match}" ]]; then
        echo "${row} $(echo ${match} | cut -d' ' -f8)";
    else
        echo "${row} NA";
    fi;
done < snp.bed

엄격한 텍스트 처리를 위해 Bash를 사용하는 것은 일반적으로 권장되지 않습니다. 예를 들어 다음 게시물을 참조하세요.

관련 정보