
비슷한 콘텐츠가 포함된 수많은 CSV 파일이 있습니다. 값은 일반적으로 쉼표로 구분되며 다음과 같습니다.
product_a, domestic, 500
product_a, abroad, 15
product_b, domestic, 313
product_b, abroad, 35
product_c, domestic, 411
product_c, abroad, 84
product_d, domestic, 25
product_d, abroad, 2
...
AWK를 사용하여 달성하려는 작업은(SED가 이러한 작업에 적합한 도구는 아니지만 상대적으로 새로운 Linux 사용자이기 때문에...) 열로 삽입된 각 제품(열 1)의 합계입니다. 2번. 난 이런 걸 할 수 있어
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename
해당 값(합계)을 얻으려면
product_a, 515
product_b, 348
product_c, 495
product_d, 27
...
하지만 여전히 다음과 같은 형식으로 원본 파일의 두 번째 열로 삽입하는 방법을 모르겠습니다.
product_a, 515, domestic, 500
product_a, 515, abroad, 15
product_b, 348, domestic, 313
product_b, 348, abroad, 35
product_c, 495, domestic, 411
product_c, 495, abroad, 84
product_d, 27, domestic, 25
product_d, 27, abroad, 2
...
나는 최근에 약간의 sed와 awk를 사용하고 있지만 일반적으로 시도하면 오류가 발생합니다(예: 스칼라 값을 배열로 사용하려고 시도).
행 순서는 내 관심사가 아니지만 답변을 배치 파일 명령으로 사용할 수 있다고 가정합니다.
$ for f in *.csv; do
That Shiny Enigmatic Command > tmp && mv tmp $f
done
편집하다
@KM님 감사합니다. 나는 내가 원하는 것을 3단계로 할 수 있는 곳에 이르렀다.
1단계:
$ for f in *.csv; do
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' $f | sort > sum$f
done
2단계:
$ for f in [^sum]*.csv; do
join -t ',' $f sum$f | awk -F, '{print $1"," $4"," $2"," $3}' > tmp && mv tmp $f;
done
결국 rm sum*.*
. 터미널에서 하나의 명령으로 실행하는 방법이 있습니까? 아니면 그 밖에서?
답변1
sum
합계를 , 정렬 된 파일에 저장합니다.
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename | sort > sum
cat sum
product_a, 515
product_b, 348
product_c, 495
product_d, 27
두 파일을 결합합니다. 첫 번째 파일의 첫 번째 열과 두 번째 파일의 첫 번째 열("키"를 생각하세요)입니다. 파이프를 통해 필드 구분 기호( ) 를 awk
사용하여 재정렬된 열을 인쇄합니다.,
-F
그리고출력 필드 구분 기호( -OFS
)
join -t ',' -1 1 -2 1 filename sum | awk -F, -OFS=, {'print $1,$4,$2,$3}'
product_a, 515, domestic, 500
product_a, 515, abroad, 15
product_b, 348, domestic, 313
product_b, 348, abroad, 35
product_c, 495, domestic, 411
product_c, 495, abroad, 84
product_d, 27, domestic, 25
product_d, 27, abroad, 2