2012-03-09 2 views
4

나는 같은 순서로 두 파일을 가지고 있고 그들은 같은 수의 행이 있습니다두 파일을 awk로 병합하는 방법은 무엇입니까?

파일 1 (만 2 열) :

562_201 RIR1 
562_202 RIR1 
562_203 RIR1 
562_204 RIR1 
562_205 RIR1 
562_206 RIR1 
562_207 RIR1 
562_208 RIR1 
562_209 RIR1 
562_210 WR1 
562_211 WR1 
562_212 WR1 

파일 2 (I 그 파일 2 이상 만 개 행이 말을해야을 !) : 내가 그들을 병합 할

562_201 0101 
562_202 0101 
562_203 0101 
562_204 0101 
562_205 0101 
562_206 0101 
562_207 0101 
562_208 0101 
562_209 0101 
562_210 0101 
562_211 0101 
562_212 0101 

하고 얻을 :

562_201 RIR1 0101 
562_202 RIR1 0101 
562_203 RIR1 0101 
562_204 RIR1 0101 
562_205 RIR1 0101 
562_206 RIR1 0101 
562_207 RIR1 0101 
562_208 RIR1 0101 
562_209 RIR1 0101 
562_210 WR1 0101 
562_211 WR1 0101 
562_212 WR1 0101 

감사합니다!

+0

을 제거하기 위해'나는 이상 만 나는 어떻게이 땅에서 알 수 columns'있다 그 파일이 생성되고 있습니까? – anubhava

+0

그것은 snp 값싼 데이터입니다 – mahmood

답변

10

당신은 join 명령을 사용할 수 있습니다 : 잘 모르겠어요

$ join file1.txt file2.txt 
+0

고전적인 유닉스 도구 추천을위한 또 다른 +1. :) – ghoti

+1

'join'은 조인 필드에서 파일을 정렬해야합니다. 두 파일 모두 열 1로 정렬하면 운이 좋습니다. –

5

AWK

awk 'NR==FNR{a[$1]=$2;next;}gsub($1,$1" "a[$1])' file1 file2 
+0

NR, FNR을 사용하여 첫 번째 파일의 데이터를 저장하고 'gsub'를 사용하여 일반 키로 출력 하시겠습니까? – staticor

6

을하지만, join 명령은 메모리에 두 파일을로드 할 수 있습니다. 파일 중 하나 또는 둘 다 막대한 경우 문제가 될 수 있습니다.

이렇게하면 작은 파일을 메모리의 배열로로드 한 다음 파이프를 통해 데이터를 조인하면 문제가 발생하지 않습니다.

#!/usr/bin/awk -f 

# Load file1 into an array... 
BEGIN { 
    while (getline < "file1") { 
    file1[$1]=$0; 
    } 
} 

{ 
    key=$1; # Store the key 
    $1="";  # Blank the key (now $0 starts with the field separator) 
    print file1[key] $0; 
} 

사용법 :

[[email protected] ~/tmp]$ ./join.awk file2 
562_201 RIR1 0101 
562_202 RIR1 0101 
562_203 RIR1 0101 
562_204 RIR1 0101 
562_205 RIR1 0101 
562_206 RIR1 0101 
562_207 RIR1 0101 
562_208 RIR1 0101 
562_209 RIR1 0101 
562_210 WR1 0101 
562_211 WR1 0101 
562_212 WR1 0101 

글렌 제안으로 표기 :

awk 'NR==FNR {file1[$1]=$0; next} {$1=file1[$1]; print}' file1 file2 

배열에 첫 번째 파일을로드의 같은 생각에 더 고전적인 방법입니다.

: 이러한 파일의 경우

는 수백만 개의 행과 함께, 당신은 또한 메모리에 각 파일에서 한 번에 하나 개의 라인을 로딩 자체 파이프의 각 파일을 통해 단계 수, 메모리에 저장하기에 너무 큰

$ awk '{getline line < "file1"; print line,$2}' file2 

이것은 file2의 행을 읽고 모든 행에 대해 file1의 행을 변수로 읽은 다음 file2의 변수와 추가 필드를 인쇄합니다. 한 번에 한 줄만 메모리에 저장됩니다.

마찬가지로, 첫 번째 필드는 항상 각 파일에서 일치한다고 가정합니다. 즉, 오류 검사는 없습니다. 당신은 어떤을 원하는 경우에, 그것을 구현할 수있을만큼 쉽게 :

$ awk '{getline line < "file1"; split(line,a); if(a[1]!=$1) {exit(1)} print line,$2}' file2 

이 일치하지 않는 1 $1 경우의 종료 상태로 종료됩니다.

+1

다음과 같이 작성할 수 있습니다 :'awk 'NR == FNR {file1 [$ 1] = $ 0; 다음} {$ 1 = 파일 [$ 1]; 인쇄} 'file1 file2'. 또한 전체 file1을 메모리에 보유해야하므로 너무 커서는 안됩니다. –

+0

물론, 배열을 사용하지 않는 마지막 두 예제를 보여주기 위해 다른 방법으로 사용한 것 같습니다. 메모리 사용에 관심이 있다면 여러 파일 핸들에서 온 디맨드를 읽을 수 있습니다. – ghoti

1
paste file1 file2 | awk '{$3=""; print}' 

는 설명 :

  1. paste f1 f2 :
  2. $3=""; print 라인
  3. 에 의해 병합 라인 : 반복 열
+0

코드가하는 일에 대한 간략한 설명을 추가하면 항상 더 좋습니다. – ianaya89

+0

@ ianaya89 : true! 그것을 할 수 있습니다! – JJoao

관련 문제