첫 번째 열로 여러 파일 병합

첫 번째 열로 여러 파일 병합

내 문제는 다음과 유사합니다.첫 번째 열 값을 기준으로 여러 열 병합

여러 개의 파일(10개 이상)이 있고 이를 하나의 출력 파일로 병합/결합하고 싶습니다. 예를 들면 다음과 같습니다.

파일 1

2000 0.0202094
2001 0.0225532
2002 0.02553
2003 0.0261099
2006 0.028843

파일 2

2000 0.0343179
2003 0.039579
2004 0.0412106
2006 0.041264

파일 3

2001 0.03
2004 0.068689
2006 0.0645474

모든 파일은 동일한 두 개의 열을 가지며 길이가 다양합니다. 열 항목이 없으면(하나 이상의 파일에서 누락됨) 1이 필요합니다. 파일에 항목이 없으면(예: 2005) 출력을 원하지 않습니다.

원하는 출력은 다음과 같습니다.

        file1       file2       file3
2000    0.0202094   0.0343179   1
2001    0.0225532   1           0.03
2002    0.02553     1           1
2003    0.0261099   0.0395799   1
2004    1           0.0412106   0.0686893
2006    0.028843    0.041264    0.0645474

다른 질문에 대한 답변에 제공된 awk 코드를 수정해 보았지만 해결이 불가능한 것 같습니다.

답변1

사용 join:

join -a1 -a2 -e 1 -o auto <(join -a1 -a2 -e 1 -o auto file1 file2) file3

에서 본남자들이 가입하다

-파일 번호
또한 FILENUM이 FILE1 또는 FILE2에 해당하는 FILENUM이 1 또는 2인 파일 FILENUM에서 페어링할 수 없는 줄을 인쇄합니다.

-e 비어 있음
누락된 입력 필드를 EMPTY로 바꾸기

-o 형식
출력 행을 작성할 때 FORMAT을 따르세요.

FORMAT이 "auto" 키워드인 경우 각 파일의 첫 번째 줄은 줄당 출력되는 필드 수를 결정합니다.

참고: 조인에는 정렬된 입력이 필요하므로 이러한 입력이 정렬되지 않은 경우(주어진 샘플에 있음) 먼저 정렬하십시오. 예:

join -a1 -a2 -e 1 -o auto \
    <(join -a1 -a2 -e 1 -o auto <(sort file1) <(sort file2)) \
    <(sort file3)

여러 파일에 적용하려면:

  1. 처음 두 파일을 연결하고 출력을 세 번째 파일에 저장합니다.join.tmp:

    join -a1 -a2 -e 1 -o auto file1 file2 >join.tmp
    
  2. next는 나머지 파일과 업데이트를 반복합니다.join.tmp각 실행에 대한 파일:

    for file in rest_files*; do
        join -a1 -a2 -e 1 -o auto join.tmp "$file" >join.tmp.1
        mv join.tmp.1 join.tmp
    done
    
  3. 드디어 너의 것join.tmp최종 연결 결과가 됩니다.


제목과 함께 인쇄:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto \
      <(join -a1 -a2 -e 1 -o auto <( hdr file1) <(hdr file2)) \
      <(hdr file3) |tr -d '\0'

다중 파일 버전의 경우:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto <(hdr file1) <(hdr file2) >join.tmp
$ for file in rest_files*; do
     join -a1 -a2 -e 1 -o auto join.tmp <(hdr "$file") >join.tmp.1
     mv join.tmp.1 join.tmp
  done
$ tr -d '\0' <join.tmp >final.file

답변2

약간 투박하지만 이 awk코드는 작동합니다. 사용하는 옵션의사 다차원 배열배열 인덱스와 SUBSEP 연결. 모든 데이터를 RAM에 보관하므로 이 경우에는 제한됩니다.

{x[$1]=$1 ; file[FILENAME]=FILENAME ; y[$1,FILENAME]=$2}

END { for (i in file) { printf "\t%s",file[i] } ; printf "\n",""
      for (i in x) { printf "%s",x[i]
        for (j in file) { if (y[x[i],file[j]] != "")
                             { printf"\t%s",y[x[i],file[j]] }
                          else { printf"\t%s","1"}
        }
        printf "\n",""
      }
    }

출력은 탭으로만 구분됩니다. 고정 형식의 경우 printf 명령을 그에 맞게 조정해야 합니다.

    file1   file2   file3
2000    0.0202094   0.0343179   1
2001    0.0225532   1   0.03
2002    0.02553 1   1
2003    0.0261099   0.039579    1
2004    1   0.0412106   0.068689
2006    0.028843    0.041264    0.0645474

관련 정보