폴더에 여러 개의 큰 csv 파일이 있고 이를 하나의 csv로 바인딩(결합)하려고 합니다. 그런데 이렇게 할 때, 연결 후 모든 컬럼 값이 해당 컬럼에 들어가는지 확인하고 싶습니다. 메모리 제한으로 인해 R에서는 이 작업을 수행할 수 없습니다. 저는 쉘 스크립팅을 처음 접했고 모든 csv 파일을 메모리에 넣지 않고도 이 작업을 수행할 수 있는 방법이 있을 수 있다는 것을 알고 있습니다.
예를 들어.
> csv1
A B C D E
1 2 4 5 6
4 5 7 8 9
3 5 6 7 8
2 3 4 5 8
> csv1
C B E D A
10 22 43 35 66
14 15 37 48 99
33 25 56 67 88
> Desired Output
A B C D E
1 2 4 5 6
4 5 7 8 9
3 5 6 7 8
2 3 4 5 8
66 22 10 35 43
99 15 14 48 37
88 25 33 67 56
내 시도:
저장 시 각 파일에 대해 R에서 열 순서를 설정한 후 아래 코드를 사용하여 연결해 보았습니다. 나는 리눅스 쉘에서 이 모든 것을 할 수 있는 방법을 알고 싶습니다.
내 시도:
nawk 'FNR==1 && NR!=1{next;}{print}' *.csv > result.csv
Any help is highly appreciated.
RavindraSingh13의 솔루션-
awk '
BEGIN{
PROCINFO["sorted_in"] = "@ind_num_asc"
}
FNR==1{
for(i=1;i<=NF;i++){
a[$i]=i};
if(FNR==1 && FNR==NR){
print};
next
}
{
for(j in a){
printf("%s ",$a[j])}
print ""
}
' csv1 csv2
그러나 위의 솔루션에서는 연결하는 동안 일부 줄을 건너뜁니다.
답변1
암소 비슷한 일종의 영양awk
해결책. 그러나 메모리의 모든 값을 매핑합니다.
merge_by_headers.awk
스크립트:
#!/bin/awk -f
BEGIN{ PROCINFO["sorted_in"] = "@ind_str_asc" }
NR==1 || FNR==1{
for (i=1; i<=NF; i++) map[i] = $i;
c = NF; next
}
NR==FNR{
row_cnt = NR-1;
for (i=1; i<=NF; i++) a[map[i]][row_cnt] = $i;
next
}
{
row_cnt += 1;
for (i=1; i<=NF; i++) a[map[i]][row_cnt] = $i;
}
END{
delete map; h = "";
for (k in a) h = (h? h OFS:"")k;
print h;
for (i=1; i<=row_cnt; i++) {
cnt = c;
for (k in a) printf "%d%s", a[k][i], (--cnt? OFS : ORS)
}
}
용법:
awk -f merge_by_headers.awk 1.csv 2.csv | column -t
산출:
A B C D E
1 2 4 5 6
4 5 7 8 9
3 5 6 7 8
2 3 4 5 8
66 22 10 35 43
99 15 14 48 37
88 25 33 67 56