첫 번째 파일의 첫 번째 열에 있는 모든 값을 기준으로 2개의 파일을 병합합니다.

첫 번째 파일의 첫 번째 열에 있는 모든 값을 기준으로 2개의 파일을 병합합니다.

다음 두 파일을 병합해야 합니다.

  • 파일 1:

표 REF-IO HEAD-IO DIFF-IO
테스트 200 500 -300
시험 2 3 -1
최종 2 1 1
메일 4 2 2
합계 208 506 -298

  • 파일 2:

테이블 참조 선택 헤드 선택 비교 선택
테스트 5 7 -2
경쟁 3 3 0
시험 0 7 -7
최종 12 6 6
합계 20 23 -3

병합된 파일은 다음과 같아야 합니다.

테이블 REF-IO HEAD-IO DIFF-IO REF-SELECT HEAD-SELECT DIFF-SELECT
테스트 200 500 -300 5 7 -2
시험 2 3 -1 0 7 -7
최종 2 1 1 12 6 6
메일 4 2 2 0 0 0합계
208 506 -298 20 23 -3

답변1

awk '
    NR==FNR {vals[$1] = $2 " " $3 " " $4; next} 
    !($1 in vals) {vals[$1] = "0 0 0"} 
    {$(NF+1) = vals[$1]; print}
' file2 file1
TABLES REF-IO HEAD-IO DIFF-IO REF-SELECT HEAD-SELECT DIFF-SELECT
test 200 500 -300 5 7 -2
exam 2 3 -1 0 7 -7
final 2 1 1 12 6 6
mail 4 2 2 0 0 0
TOTAL 208 506 -298 20 23 -3

답변2

join행 순서, 머리글, 바닥글 등을 사용하고 보존하는 방법은 다음과 같습니다 .

join -1 2 -2 1 -a 1 -e 0 -o 1.1,1.2,1.3,1.4,1.5,2.2,2.3,2.4 \
<(sort -k2,2 <(nl -ba -nrz file1)) <(sort -k1,1 file2) | \
sort -k1,1n | cut -d\  -f2-

결과:

TABLES REF-IO HEAD-IO DIFF-IO REF-SELECT HEAD-SELECT DIFF-SELECT
test 200 500 -300 5 7 -2
exam 2 3 -1 0 7 -7
final 2 1 1 12 6 6
mail 4 2 2 0 0 0
TOTAL 208 506 -298 20 23 -3

작동 방식:

nl -ba -nrz file1행에 번호를 매기고 file1출력 sort을 두 번째 필드에 추가합니다. file2또한 sort첫 번째 필드를 편집하고 결과를 join첫 번째 입력의 두 번째 필드와 두 번째 입력의 첫 번째 필드에 추가하고 누락된 입력 필드를 다음으로 바꿉니다 0.

000003 exam 2 3 -1 0 7 -7
000004 final 2 1 1 12 6 6
000005 mail 4 2 2 0 0 0
000001 TABLES REF-IO HEAD-IO DIFF-IO REF-SELECT HEAD-SELECT DIFF-SELECT
000002 test 200 500 -300 5 7 -2
000006 TOTAL 208 506 -298 20 23 -3

그런 다음 첫 번째 필드를 정렬하여 sort -k1,1n행 순서를 복원한 다음 cut -d\ -f2-행 번호를 제거합니다. 예를 들어 다음 column을 사용하여 더욱 아름답게 만들 수 있습니다 .... | column -t.

TABLES  REF-IO  HEAD-IO  DIFF-IO  REF-SELECT  HEAD-SELECT  DIFF-SELECT
test    200     500      -300     5           7            -2
exam    2       3        -1       0           7            -7
final   2       1        1        12          6            6
mail    4       2        2        0           0            0
TOTAL   208     506      -298     20          23           -3

답변3

이 스크립트는 다음과 같이 작동해야 합니다.

touch resultFile
while read f; do
    header1=$(echo $f | awk '{print $1;}');
    values1=$(echo $f | awk -F "$header1 " '{print $NF;}');
    while read g; do
        header2=$(echo $g | awk '{print $1;}');
        values2=$(echo $g | awk -F "$header2 " '{print $NF;}');
        if [ $header1 = $header2 ]; then
            echo "$header1 $values1 $values2" >> resultFile
        fi
    done < file2
done < file1

헤더는 고유해야 합니다. 그렇지 않으면 발견된 마지막 행만 병합됩니다.

추신: "Mail" 헤더는 "Game" 때문에 두 파일 모두에 없기 때문에 결과에 없어야 한다고 생각합니다(귀하의 예에서는 "Mail"은 있지만 "Game"은 없습니다).

답변4

궁금하시다면,join행 순서는 유지되지 않지만 다음을 사용하여 이를 수행할 수 있습니다.

(
  join <(head -n1 file1) <(head -n1 file2)
  join -a 1 -e 0 -o '0 1.2 1.3 1.4 2.2 2.3 2.4' \
                    <(sed -n 2,5p file1 | sort) \
                    <(sed -n 2,5p file2 | sort)
  join <(tail -n1 file1) <(tail -n1 file2)
)

산출:

TABLES REF-IO HEAD-IO DIFF-IO REF-SELECT HEAD-SELECT DIFF-SELECT
exam 2 3 -1 0 7 -7
final 2 1 1 12 6 6
mail 4 2 2 0 0 0
test 200 500 -300 5 7 -2
TOTAL 208 506 -298 20 23 -3

관련 정보