다른 파일의 범위에 속하는 범위를 기반으로 파일에서 줄 추출

다른 파일의 범위에 속하는 범위를 기반으로 파일에서 줄 추출

ca.라는 파일이 있습니다. 2열과 3열(범위의 시작과 끝)의 값을 기준으로 17000개의 행을 추출해야 합니다.

File_1.txt

NC_018723.3 88839   102219
NC_018723.3 156206  160651
NC_018723.3 160885  165615
NC_018723.3 178410  191119
NC_018723.3 226179  242932
NC_018723.3 243929  310071
NC_018723.3 384020  413475

범위가 포함된 두 번째 파일이 있습니다.

File_2.txt

8410001 8420000
8420001 8430000
28550001    28560000
28560001    28570000
111910001   111920000
111920001   111930000
209310001   209320000
209320001   209330000
209330001   209340000

2열과 3열의 범위가 file_2.txt 범위에 속하는 file_1.txt에서 행을 추출하는 방법을 찾고 있습니다.

어떤 아이디어라도 크게 감사하겠습니다.

답변1

TXR 불분명한 음성해결책.

먼저, file_1.txt실제로 다음 범위에 속하는 몇 가지 범위 사례가 추가되었습니다 file_2.txt.

NC_018723.3 88839   102219
NC_018723.3 156206  160651
NC_018723.3 160885  165615
NC_018723.3 178410  191119
NC_018723.3 226179  242932
NC_018723.3 243929  310071
NC_018723.3 384020  413475

FOO_1 8420001 8430000
FOO_2 8430000 8440000
FOO_3 8430000 8440000
FOO_4 209310001 209320001
FOO_5 209310001 209320000
FOO_6     209310002 209320000
FOO_7 209310002 209319999

달리기:

$ txr soln.tl 
FOO_1 8420001 8430000
FOO_5 209310001 209320000
FOO_6 209310002 209320000
FOO_7 209310002 209319999

코드는 다음 위치에 있습니다 soln.tl.

(defvarl rtree [tree nil to])

(defun add-range (tree range)
  (tree-insert tree range))

(defun lookup-range (tree range)
  (let* ((iter (tree-begin tree (from range)))
         (node (tree-next iter))
         (found (if node (key node))))
    (if (and found
             (>= (from range) (from found))
             (<= (to range) (to found)))
      found)))

(awk
  (:inputs "file_2.txt")
  (t (fconv i i) (add-range rtree [f 0]..[f 1])))

(awk
  (:inputs "file_1.txt")
  (t (fconv - i i)
     (if (lookup-range rtree [f 1]..[f 2])
       (prn))))

여기서 접근 방식은 이진 검색 트리를 사용하여 범위를 저장하는 것입니다 file_2.txt.

TXR Lisp에는 범위 유형이 있습니다: 접근자 fromto. REPL에서 이를 탐색할 수 있습니다.

1> 10..20
#R(10 20)
2> (typeof *1)
range
3> (from *1)
10
4> (to *1)
20

soln.tl프로그램 에서 표현식은 [tree nil to]새로운 이진 검색 트리를 구성합니다. nil비워 두는 것이 to핵심 기능입니다. to범위 필드에 액세스하는 함수 라는 점에 유의하세요 . 우리는 이 트리에 범위 개체를 넣을 것이고, to해당 개체의 필드에 키가 설정될 것입니다.

함수가 lookup-range가장 복잡합니다. 입력 범위가 주어지면 해당 범위가 트리에 저장된 범위 내에 포함되는지 여부를 결정합니다. tree-begin순차적으로 트리 탐색을 시작하지만 입력 범위 필드 to보다 낮은 키(즉, 필드) 가 있는 모든 노드를 무시하는 데 사용됩니다 . from즉, 검색 범위의 필드 to보다 큰 가장 낮은 필드를 가진 노드를 찾고 있습니다.from

노드가 발견되면 간단한 중첩 테스트를 적용하여 이를 확인합니다.

함수 정의 뒤에는 두 개의 표현식이 있습니다 (awk ..). 첫 번째 awk프로세스는 file_2.txt트리 해시를 채웁니다. Awk fconv연산자는 필드를 정수로 변환하고 [f 0]..[f 1]그로부터 범위 개체를 구성하는 데 사용됩니다.

두 번째 {awk ...)작업은 file_1.txt범위 검색 및 일치하는 레코드 인쇄를 처리합니다.

균형 이진 트리는 범위에 사용되므로 file_2.txt크기가 커질 수 있습니다.

로 필드를 수정했기 때문에 공백은 출력에 보존되지 않습니다 fconv. Awk에서는 필드에 할당하면 출력 필드 구분 기호를 사용하여 필드를 연결하여 레코드 이미지를 다시 계산합니다.

공백을 유지하기 위해 awk두 번째 공백을 이렇게 변경할 수 있습니다. 우리는 지역 변수를 도입하고 이를 사용하여 기록된 recsave값을 유지합니다(클래식 Awk에서와 마찬가지로).rec$0

(awk
  (:inputs "file_1.txt")
  (:let recsave)
  (t (set recsave rec)
     (fconv - i i)
     (if (lookup-range rtree [f 1]..[f 2])
       (prn recsave))))

관련 정보