비슷한 콘텐츠가 포함된 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)을 합산하는 것입니다. nr 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