미리 정렬된 탭으로 구분된 파일을 병합하고 싶습니다.
- 문서
bygroup.0
:ancient-american mercury 1 164 ancient-american mh25 2 8717664 ancient-neolith tk11 262 40074321970 ancientdna jk21 6936 17069206689 ancientdna rm20 11267 372606702813 ancientgen ab34 1573 27800468142 ancientgen dg11 3516 45081427920 ancientgen fa8 7179 462396221983 ancientgen mp15 41 10248223517 ancientgen mp18 254 1049351143 ancientgen rm20 15100 1565340401 ancientgen tc9 1695 89861489631
- 문서
bygroup.2
:ancient-american mercury 1 160 ancient-american mh25 2 10362712888 ancient-neolith tk11 264 43842268110 ancientdna jk21 6919 16379509855 ancientdna rm20 11268 324906365415 ancientgen ab34 1577 33947364202 ancientgen dg11 3518 48092138390 ancientgen fa8 7174 472364587220 ancientgen mp15 39 32487920045 ancientgen mp18 254 1058177852 ancientgen rm20 15104 998615135 ancientgen tc9 1692 94858351562
두 파일 모두 동일한 행 수를 가지며 열 1과 2를 기준으로 동일한 순서로 되어 있으며 해당 열의 항목이 동일하다는 것을 알 수 있습니다.
이제 처음 두 열의 값이 동일한 모든 행이 순서대로 출력되도록 병합하고 싶습니다.
sort -m
나는 이것이 나에게 필요한 것이라고 생각했지만 ,
$ sort -m bygroup.*
ancient-american mercury 1 160
ancient-american mercury 1 164
ancient-american mh25 2 10362712888
ancient-american mh25 2 8717664
ancient-neolith tk11 262 40074321970
ancientdna jk21 6936 17069206689
ancientdna rm20 11267 372606702813
ancientgen ab34 1573 27800468142
ancientgen dg11 3516 45081427920
ancientgen fa8 7179 462396221983
ancientgen mp15 41 10248223517
ancientgen mp18 254 1049351143
ancientgen rm20 15100 1565340401
ancientgen tc9 1695 89861489631
ancient-neolith tk11 264 43842268110
ancientdna jk21 6919 16379509855
ancientdna rm20 11268 324906365415
ancientgen ab34 1577 33947364202
ancientgen dg11 3518 48092138390
ancientgen fa8 7174 472364587220
ancientgen mp15 39 32487920045
ancientgen mp18 254 1058177852
ancientgen rm20 15104 998615135
ancientgen tc9 1692 94858351562
(내가 추가한 다른 옵션에서도 동일한 결과를 얻었습니다. sort -k 1,2 -ifm
...)
그것은 고대 미국인에 대한 나의 기대에 부합하지만 다른 사람들에게는 그렇지 않습니다. 무슨 일이 일어나고 있으며 전체 정렬( sort
여기서는 필요 없이 작동함 -m
)에 의존하지 않고 이 작업을 수행할 수 있는 또 다른 빠르고 효율적인 방법이 있습니까?
답변1
TXR Lisp 솔루션:
$ txr merge.tl
ancient-american mercury 1 164
ancient-american mercury 1 160
ancient-american mh25 2 8717664
ancient-american mh25 2 10362712888
ancient-neolith tk11 262 40074321970
ancient-neolith tk11 264 43842268110
ancientdna jk21 6936 17069206689
ancientdna jk21 6919 16379509855
ancientdna rm20 11267 372606702813
ancientdna rm20 11268 324906365415
ancientgen ab34 1573 27800468142
ancientgen ab34 1577 33947364202
ancientgen dg11 3516 45081427920
ancientgen dg11 3518 48092138390
ancientgen fa8 7179 462396221983
ancientgen fa8 7174 472364587220
ancientgen mp15 41 10248223517
ancientgen mp15 39 32487920045
ancientgen mp18 254 1049351143
ancientgen mp18 254 1058177852
ancientgen rm20 15100 1565340401
ancientgen rm20 15104 998615135
ancientgen tc9 1695 89861489631
ancientgen tc9 1692 94858351562
암호:
(defstruct record ()
key
line
(:method equal (me) me.key))
(defun read-recs (file)
(build
(awk (:set fs "\t")
(:inputs file)
(t (add (new record
key [f 0..2]
line rec))))))
(mapdo [chain .line put-line] (merge (read-recs "bygroup.0") (read-recs "bygroup.1")))
파일의 각 레코드에 대한 정보를 보유하기 위해 정렬 키인 record
a 와 원시 축어 행인 a를 포함하는 구조 유형을 정의합니다. 슬롯 은 두 개의 문자열 목록이 됩니다.key
line
key
이 record
유형에는 equal
다음을 구현하는 메소드 가 있습니다.동등한 대체. 즉, record
함수가 전달되거나 equal
객체 less
가 비교될 때마다 greater
객체 대신 해당 메서드의 값이 사용됩니다. 예를 들어, 비교 함수를 지정하지 않고 sort
구조체 목록에 액세스한다면 record
해당 구조체는 키를 기준으로 정렬됩니다.
이 함수는 read-recs
표준 awk
Awk에서 필드 구분 기호를 "\t" (tab). For each record, the
t condition (unconditional truth) dispatches an action which creates a record object. The
key is a sublist of the
f (field) list, consisting of the first two fields. The
line is the
rec $0`로 지정합니다.: the whole record.
is like
이 build
매크로는 암시적, 절차적 목록 작성에 사용됩니다. 예를 들어 (build (add 1) (add 2))
목록이 반환됩니다 (1 2)
. 종료 시 반환되는 build
암시적 숨겨진 목록에 호출이 추가되는 범위를 만듭니다 .add
build
read-recs
등치 치환을 사용하면 필요한 키를 올바르게 입력하는 유형이 있으므로 두 파일을 모두 읽고 정렬된 목록을 얻기 위해 record
함수에 전달하기만 하면 됩니다 .merge
record
이 목록의 개체는 두 가지 함수의 연결을 통해 매핑됩니다. [chain .line put-line]
이 함수는 개체의 슬롯을 .line
검색 한 다음 이를 표준 출력에 덤프하고 그 뒤에 개행 문자가 옵니다.line
put-line
read-recs
and를 사용하지 않고 build
함수를 구현하는 방법은 다음 awk
과 같습니다.
(defun read-recs (file)
(collect-each ((line (file-get-lines file)))
(let ((fields (spl #\tab line)))
(new record key [fields 0..2]
line line))))
답변2
R 프로그래밍 언어 사용
하나 이상의 공백 문자를 단일 탭 문자로 대체하여 텍스트 파일을 저장합니다. 두 개의 데이터 파일을 R로 읽습니다.
> group0 <- read.delim("/Users/admin/bygroup.0", header=FALSE)
> group2 <- read.delim("/Users/admin/bygroup.2", header=FALSE)
> head(group0)
V1 V2 V3 V4
1 ancient-american mercury 1 164
2 ancient-american mh25 2 8717664
3 ancient-neolith tk11 262 40074321970
4 ancientdna jk21 6936 17069206689
5 ancientdna rm20 11267 372606702813
6 ancientgen ab34 1573 27800468142
> head(group2)
V1 V2 V3 V4
1 ancient-american mercury 1 160
2 ancient-american mh25 2 10362712888
3 ancient-neolith tk11 264 43842268110
4 ancientdna jk21 6919 16379509855
5 ancientdna rm20 11268 324906365415
6 ancientgen ab34 1577 33947364202
데이터 파일을 병합하려면 R의 merge()
기능을 사용하십시오.
> merge(group0, group2, by = c("V1","V2"))
V1 V2 V3.x V4.x V3.y V4.y
1 ancient-american mercury 1 164 1 160
2 ancient-american mh25 2 8717664 2 10362712888
3 ancient-neolith tk11 262 40074321970 264 43842268110
4 ancientdna jk21 6936 17069206689 6919 16379509855
5 ancientdna rm20 11267 372606702813 11268 324906365415
6 ancientgen ab34 1573 27800468142 1577 33947364202
7 ancientgen dg11 3516 45081427920 3518 48092138390
8 ancientgen fa8 7179 462396221983 7174 472364587220
9 ancientgen mp15 41 10248223517 39 32487920045
10 ancientgen mp18 254 1049351143 254 1058177852
11 ancientgen rm20 15100 1565340401 15104 998615135
12 ancientgen tc9 1695 89861489631 1692 94858351562
write.delim()
또는 함수를 사용하여 데이터를 다시 쓸 수 있습니다 write.csv()
. 도움말을 보려면 프롬프트에 , 또는 ?getwd()
와 같은 물음표 앞에 명령을 입력하세요 ?setwd()
.?read.delim()
?merge()
[참고: R 설치 기간에 따라 stringsAsFactors=FALSE
모든 함수 호출 read.delim()
에 이 인수를 포함 해야 할 수도 있습니다.]
https://www.r-project.org/
https://cran.r-project.org/index.html