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.csv
2.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