동일한 필드의 정렬 값을 기준으로 두 개의 정렬된 파일을 병합합니다.

동일한 필드의 정렬 값을 기준으로 두 개의 정렬된 파일을 병합합니다.

길이가 반드시 같을 필요는 없지만 동일한 데이터 필드와 동일한 헤더를 사용하여 특정 열의 순서에 따라 유지되는 헤더 다음에 시작하여 두 개의 정렬된 파일의 행을 병합하고 싶습니다. 예를 들어 파일 1은 다음과 같습니다.

header 1
header 2
header 3

cat    4    aa
dog    5    ab
ostrich    10    cd
fish    13    cc

파일 2는 다음과 같습니다.

header 1
header 2
header 3

lemur    3    dd
alligator    4    ca
lemming    16    ad

1) 동일한 헤더를 유지하고 싶지만 2) 열 2를 기준으로 다음 행을 정렬하고 싶습니다. 내가 원하는 출력은 다음과 같습니다.

header 1
header 2
header 3

lemur    3    dd
cat    4    aa
alligator     4    ca
dog    5    ab
ostrich    10    cd
fish    13    cc
lemming     16    ad

찾아봤지만 awk또는 을 사용하여 이 상황에 대한 해결책을 찾을 수 없습니다 join.

답변1

awk그리고 join잘못된 도구입니다.

sed '/^$/q' file1; sort -snmk2,2 <(sed '1,/^$/d' file1) <(sed '1,/^$/d' file2)

답변2

최신 (버전> 4.0) GNU awk를 사용하면 할 수 있습니다

awk '
  FNR>4 {a[$0]=$2; next}; 
  NR==FNR; 
  END {
    PROCINFO["sorted_in"] = "@val_num_asc"; 
    for (i in a) print i;
  }
' file1 file2

설명하다:

  • FNR>4 {a[$0]=$2; next};머리글이 아닌 행에 대한 정렬 필드 배열 만들기
  • NR==FNR;첫 번째 파일에 대해서만 TRUE를 평가하고,reach에 대해서만 평가하여 FNR>4첫 번째 파일에 대해 헤더 줄이 인쇄되도록 합니다.
  • PROCINFO["sorted_in"] = "@val_num_asc"값을 기준으로 배열을 정렬합니다(예: 저장 필드 $2).
  • for (i in a) print i인쇄색인정렬된 배열(헤더가 아닌 행이 저장됨)

시험

$ awk 'FNR>4 {a[$0]=$2; next}; NR==FNR; END {PROCINFO["sorted_in"] = "@val_num_asc"; for (i in a) print i;}' file1 file2
header 1
header 2
header 3

lemur    3    dd
cat    4    aa
alligator    4    ca
dog    5    ab
ostrich    10    cd
fish    13    cc
lemming    16    ad

답변3

프로세스 대체와 함께 쉘( ksh93, , ...)을 사용하십시오 bash(프로세스 대체가 없는 대안은 끝 참조).

cat <( head -n 3 file1 ) \
    <( sort -k2,2n <( tail -n +4 file1 | tr -s ' ' '\t' ) \
                   <( tail -n +4 file2 | tr -s ' ' '\t' ) | uniq )

결과는 다음과 같습니다.

header 1
header 2
header 3

lemur   3       dd
alligator       4       ca
cat     4       aa
dog     5       ab
ostrich 10      cd
fish    13      cc
lemming 16      ad

이 명령은 헤더 행을 file1정렬 작업의 결과와 연결합니다. 정렬은 일부 입력의 두 번째 필드에서 숫자로 수행되며 중복된 행(악어, 여우원숭이, 레밍)은 uniq결과에서 제거됩니다.

file1정렬할 입력은 연속된 공백을 단일 탭으로 바꾸기 위해 file2전달된 및 의 제목 없는 내용입니다 tr(예제 데이터에는 열 사이의 공백 수가 고르지 않습니다).

결과는 탭으로 구분됩니다.


동일한 도구를 사용하는 동등한 방법:

cat <( head -n 3 file1 ) \
    <( sort -k2,2n <( cat <( tail -n +4 file1 ) \
                          <( tail -n +4 file2 ) | tr -s ' ' '\t' ) | uniq )

cats 및 프로세스 대체 없이 :

{ head -n 3 file1;
    { tail -n +4 file1; tail -n +4 file2; } | tr -s ' ' '\t' | sort -k2,2n | uniq; }

관련 정보