두 번째 파일의 범위에 속하는 열을 기반으로 파일의 행 하위 집합을 인쇄합니다.

두 번째 파일의 범위에 속하는 열을 기반으로 파일의 행 하위 집합을 인쇄합니다.

4개의 열()이 있는 파일이 있습니다 file1.txt.

chr1    1156    G       G
chr1    1157    A       A
chr1    1165    T       T
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T
chr1    1181    C       C
chr1    1186    G       G

두 번째 파일( file2.txt)에는 범위, 2개의 열이 포함됩니다.

1100    1160
1170    1180

file12열이 범위에 속하는 행을 추출하고 싶습니다 file2. 위 예에서 원하는 출력은 다음과 같습니다.

chr1    1156    G       G
chr1    1157    A       A
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T

비슷한 게시물을 기반으로 시도했지만 결과가 나오지 않았습니다.

awk 'NR==FNR{ range[$1,$2]; next }{for(x in range) {split(x, check, SUBSEP); if($2>=check[1] && $2<=check[2]) print}} ' file2.txt file1.txt > output.txt

나는 또한 같은 행운으로 다음을 시도했습니다.

awk 'NR == FNR {ref[$1][$2]} if ($1 <= key && key <= $2) sum += ref[$2][key] print $0, sum} file2.txt file1.txt > output.txt

누구든지 제안 사항이 있으면 크게 감사하겠습니다.

답변1

다음 awk프로그램은 다음을 수행해야 합니다.

awk 'NR==FNR{rng++;start[rng]=$1;end[rng]=$2;next}
     {for (i=1;i<=rng;i++) if (($2>=start[i])&&($2<=end[i])) {print; next}}' file2.txt file1.txt

작동 방식은 다음과 같습니다.

  • 첫 번째 입력 파일( file2.txt파일별 ​​라인 카운터와 동일한 전역 라인 카운터로 표시됨)을 구문 분석하는 동안 범위 시작 및 끝 번호를 두 배열에 등록하고 (한 배열의 범위 수를 계산하는 동안) 카운터) . 그 후에는 즉시 다음 실행 라인으로 점프합니다.NRFNRstartendrng
  • file1.txt( NR이제 보다 큼 )을 처리할 때 각 행의 열 2가 각각 및 배열 의 ​​해당 항목에 의해 지정된 범위 내에 FNR속하는지 확인합니다 . 그렇다면 현재 줄을 인쇄하고 다음 줄로 다시 점프합니다.startend

답변2

두 파일 모두 수천 줄 길이입니다.

따라서 지난 30년 동안의 컴퓨터에 있어서 수천 개의 행은 전혀 많은 데이터가 아닙니다. 효율성은 당신에게 중요하지 않습니다. (대략적인 계산: 첫 번째 파일은 한 줄에 32바이트이고 두 번째 파일은 한 줄에 16바이트이므로 한 줄에 총 48바이트입니다. 컴퓨터가 조금이라도 얼굴이 붉어지기 전에 2GB의 RAM 여유 공간이 있다고 가정하면 4,400만 개를 읽을 수 있습니다. 걱정하지 않고 RAM에 행을 추가하세요).

이것이 유전체학/생물정보학처럼 보이기 때문에 어쨌든 조만간 Python에 노출될 가능성이 높다고 생각합니다.

#!/usr/bin/env python3
file1 = open("file1.txt", "r", encoding="ascii")
file2 = open("file2.txt", "r", encoding="ascii")

lines1 = file1.readlines()
lines2 = file2.readlines()

file1.close()
file2.close()

for dataline, rangeline in zip(lines1, lines2):
  splitrange = rangeline.split()
  lower = int(splitrange[0])
  upper = int(splitrange[1])
  
  ignore, valuestring, nucleotide1, nucleotide2 = dataline.split()
  value = int(valuestring)
  if lower <= value and value <= upper:
    print(dataline)

그게 다야.

재중만큼 간결한가 awk? 당연히 아니지. 이것이 가능한 한 빠른가? 아니요, 전혀 그렇지 않습니다(그러나 그것은 중요하지 않습니다). 그 주에 무슨 일이 일어났는지 기억할 수 있나요? 아마도.

언급한 대로 AWK의 설계 목적과 전혀 관련이 없는 다른 작업을 수행할 가능성이 높으므로 Python은 아마도 자연스러운 도구일 것입니다. 배우는 것이 거의 확실하다.생물 파이썬좋은 생각이에요.

답변3

두 가지 호출을 사용하십시오 awk.

<file2.txt awk '{ print "$2 >= " $1 " && $2 <= " $2 }' |
           awk -f - file1.txt

답변4

cat file2 |while read line ; do col1=$(echo $line| awk '{print $1}'); col2=$(echo $line | awk '{print $2}'); cat file1|while read fine; do echo $fine |awk -v col1="$col1" -v col2="$col2" '$2 >=col1 && $2 <col2'; done; done

산출

chr1    1156    G       G
chr1    1157    A       A
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T

관련 정보