2개의 CSV 파일을 병합하여 다른 열이 하나 더 있는 하나의 CSV 파일을 만듭니다.

2개의 CSV 파일을 병합하여 다른 열이 하나 더 있는 하나의 CSV 파일을 만듭니다.

2개의 CSV 파일이 있습니다. 1.csv그들에게 전화하자2.csv

  • 첫 번째 ( 1.csv)는 다음과 같습니다.

    1,3543
    23,3632
    12,7665
    1,9795
    32,8793
    35,0290
    
  • 두 번째 파일( 2.txt)은 다음과 같습니다.

    1,4543
    3,3223
    4,1213
    6,2324
    65,3123
    32,5432
    9,9839
    5,8798
    
  • 마지막 열은 첫 번째 열과 첫 번째 열의 output.csv차이 입니다.1.csv2.txt

    1,3543,1,4543,0
    23,3632,3,3223,20
    12,7665,4,1213,8
    1,9795,6,2324,-5
    32,8793,65,3123,-23
    35,0290,32,5432,3
    ,,9,9839,NA
    ,,5,8798,NA
    

저는 쉘 스크립팅을 처음 접했습니다. 도와주세요

답변1

문제는 두 파일을 결합할 공통 필드가 없다는 것입니다. 즉시 하나를 만든 다음 awk를 다시 사용하여 다음과 같이 차이를 계산할 수 있습니다.

join -a2 -o auto -t, <(awk '{ print NR","$0 }' 1.txt ) <(awk '{ print NR","$0 }' 2.txt) \
    | awk  'BEGIN { 
        FS=OFS="," 
    } 
    { if ($2) { 
        $6=$2-$4 
    } else { 
        $6="NaN" 
    }; 
    print $2,$3,$4,$5,$6  
}'
1,3543,1,4543,0
23,3632,3,3223,20
12,7665,4,1213,8
1,9795,6,2324,-5
32,8793,65,3123,-33
35,0290,32,5432,3
,,9,9839,NaN
,,5,8798,NaN

답변2

두 파일을 함께 붙여넣으면 전체 결과를 작업할 수 있습니다.

paste -d, 1.txt 2.txt |
awk -F, 'NF < 4  { printf $1=="" ? ",%s,NA\n" : "%s,,NA\n", $0 }
         NF >= 4 { printf "%s,%d\n", $0, $1-$3 }'

이는 쉼표를 사용하여 두 파일을 연결합니다. 다른 파일에 일치하는 줄이 없으면 빈 필드로 시작하거나(두 번째 파일이 더 긴 경우) 빈 필드로 끝나는 짧은 줄이 생성됩니다(첫 번째 파일이 더 긴 경우). AWK를 사용하여 결과를 처리합니다.

  • 필드 수가 4개 미만이면 데이터가 손실됩니다. 추가 필드(앞에 또는 뒤에 오는)가 있는 행에는 "NA"가 추가되어 출력됩니다.
  • 필드 수가 4개 이상이면 모든 데이터가 존재하며, 그 뒤에 필드 1과 3의 차이가 출력됩니다.

답변3

paste -d : 1.txt 2.txt |
awk -F : -v OFS=, '
{
    split($1,a,OFS)
    split($2,b,OFS)

    $1 = a[1]; $2 = a[2]
    $3 = b[1]; $4 = b[2]
}

{
    $5 = $1 == "" || $3 == "" ? "NA" : $1 - $3
}; 1'

:이렇게 하면 .a를 구분 기호로 사용하여 두 파일을 나란히 연결합니다 paste.

명령 은 awk전처리 블록과 계산 블록으로 구분됩니다.

전처리 블록은 각 레코드에 각 파일에 2개의 필드가 있는지 확인합니다.

각 입력 라인에서 두 개의 분리된 필드를 가져와 :각 입력 라인의 쉼표로 구분된 하위 필드를 두 개의 배열로 추출 합니다 a. b각 배열에서 예상되는 두 요소는 처음 네 필드로 직접 전송됩니다. 파일 중 하나가 다른 파일보다 짧을 때마다 빈 필드가 생성됩니다.

두 번째 블록은 5번째 필드를 1번째와 3번째 필드의 차이로 계산합니다. 단, 필드 중 하나가 비어 있지 않으면 5번째 필드에 string 이 할당됩니다 NA.


전처리 블록이 각 파일에 고정된 수의 필드를 사용하여 임의의 수의 입력 파일로 일반화되는 방법을 생각해 보십시오.

paste -d : 1.txt 2.txt |
awk -F : -v OFS=, -v nf=2 '
{
    for (i = NF; i >= 1; --i) {
        split($i,a,OFS)
        for (j = 1; j <= nf; ++j)
            $((i-1)*nf + j) = a[j]
    }
}

{
    $5 = $1 == "" || $3 == "" ? "NA" : $1 - $3
}; 1'

nf이는 각 파일의 예상 필드 수를 명령줄의 인수로 전달하고 이러한 필드를 nf각각의 :구분된 입력 필드(비어 있는지 여부에 관계없이) 에 할당하여 문제를 해결합니다 .

최종 계산 블록은 이전과 동일합니다. awk코드의 첫 번째 부분을 향후 변화하는 요구 사항이나 다른 곳에서 재사용할 수 있도록 더 유연하게 만들었습니다.

답변4

paste g1.txt  g2.txt|awk '{print $1","$2}'| awk -F "," '{if (NF==4){print $0","$1-$3}else{print ",,"$0"NA"}}'

산출

1,3543,1,4543,0
23,3632,3,3223,20
12,7665,4,1213,8
1,9795,6,2324,-5
32,8793,65,3123,-33
35,0290,32,5432,3
,,9,9839,NA
,,5,8798,NA

관련 정보