두 파일을 병합한 후 열이 누락됨

두 파일을 병합한 후 열이 누락됨

file1.txt가 있습니다.

1|2022-09-29|03:15:00
2|2022-09-29|10:50:00
3|2022-09-29|07:15:00

및 파일 2.txt:

1|red|info 1
2|blue
3|yellow|info 2

이 파일들을 다음과 같이 file3.txt로 연결하고 싶습니다.

red|2022-09-29|03:15:00|info 1
blue|2022-09-29|10:50:00|
yellow|2022-09-29|07:15:00|info 2

그래서 스크립트를 입력하려고 합니다.

#!/bin/bash

awk -F'|' 'NR==FNR {a[$1]=$2;next}  ($1 in a) {a[$1]=$2"|"a[$1]"|"a[$3]"|"$3; print a[$1]}' file1.txt file2.txt > file3.txt

하지만 내 결과는 다음과 같습니다.

red|2022-09-29||info 1
blue|2022-09-29||
yellow|2022-09-29||info 2

보시다시피 file1.txt의 세 번째 부분이 누락되었으며 그 이유를 이해할 수 없습니다. 제가 뭘 잘못하고 있는지 지적해 주시면 정말 감사하겠습니다.

답변1

대답은 매우 간단합니다. a[$3]참조하는 데 사용하는 세 번째 열입니다 file1. 하지만

  • 배열을 사용하여 세 번째 열 대신 a두 번째 열을 저장하고file1
  • 첫 번째 열(숫자)만 "키"로 사용하고 있으므로 액세스를 시도하면 a["info 1"]( a[$3]처리한 첫 번째 행에서 했던 것처럼 file2) 아무 것도 반환되지 않습니다.

다음 프로그램이 이를 수행할 수 있습니다:

awk 'BEGIN{FS=OFS="|"} NR==FNR{d[$1]=$2;t[$1]=$3;next} ($1 in d) {print $2,d[$1],t[$1],$3}' file1.txt file2.txt > file3.txt

|입력 및 출력에 대한 필드 구분 기호를 설정합니다 .

  • 을 처리할 때 첫 번째 열(숫자)을 키로 하여 file1.txt날짜를 배열에 d, 시간을 배열에 저장합니다.t
  • 을 처리하는 동안 file2.txt열 1에 해당하는 날짜와 시간인 열 2를 인쇄한 다음 |출력 구분 기호로 사용되는 열 3에 "info" 값을 인쇄합니다.

답변2

다음을 신뢰할 수 있습니다 join.

join -t\| -j 1 -o 1.2,2.2,2.3,1.3 file2 file1

여기서 format( -o)은 로 정의되므로 FILE.FIELD어떤 입력 파일에서 가져올 필드를 선택하면 -t필드 구분 기호를 정의하고 -j일치를 위해 두 파일의 공통 필드를 정의하는 데 사용됩니다.

정렬이 필요할 수 있습니다.

join -t\| -j 1 -o 1.2,2.2,2.3,1.3 <(sort file2) <(sort file1)

답변3

awk 'BEGIN{FS=OFS="|"} NR==FNR {a[$1]=$2 OFS $3;next} ($1 in a) {print $2,a[$1],$3}' file1.txt file2.txt > file3.txt

이식성을 위해 저는 BEGIN{FS=OFS="|"}필드 구분자와 출력 필드 구분자를 선택할 수 있는 으로 시작했습니다.

그런 다음 첫 번째 파일에 있을 때 NR==FNR출력 필드 구분 기호로 구분된 두 번째와 세 번째 필드를 등록 {a[$1]=$2 OFS $3;next}하고 다음 줄에 도달했지만 아직 아무것도 인쇄되지 않았습니다. 스크립트에서는 세 번째 필드를 등록하지 않으므로 출력할 수 없습니다.

두 번째 파일에 도달하면 합계 NRFNR달라지며 첫 번째 필드가 array 에 있는지 확인하세요 ($1 in a). 두 번째 필드인 배열과 세 번째 필드를 등록한 후 인쇄하는 대신 바로 인쇄합니다 {print $2,a[$1],$3}.

답변4

두 입력 파일의 데이터가 포함된 구분 기호나 구분 기호인 개행 문자가 포함된 필드를 포함하지 않는 "간단한" CSV 레코드이고 |, 질문에서와 같이 파일이 한 줄씩 일치한다고 가정합니다.

awk이 두 파일은 using 에 나란히 표시될 수 paste있으며 awk필요한 순서대로 원하는 필드를 선택하는 데 사용할 수 있습니다.

paste -d '|' file1 file2 |
awk -F '|' 'BEGIN { OFS=FS } { print $5, $2, $3, $6 }' >file3

file3질문의 데이터에 대한 결과를 제공합니다.

red|2022-09-29|03:15:00|info 1
blue|2022-09-29|10:50:00|
yellow|2022-09-29|07:15:00|info 2

관련 정보