CSV 파일의 열을 별도의 파일로 분할하는 방법은 무엇입니까?

CSV 파일의 열을 별도의 파일로 분할하는 방법은 무엇입니까?

list.csv아래와 같이 csv 파일이 있습니다 .

Pcissicola19,cissicola39,12xbauhiniae
BGDHLHFA_02833,DGDFDEGP_00879,POPGJMOL_04119
BGDHLHFA_01427,DGDFDEGP_03106,POPGJMOL_01558
BGDHLHFA_01618,DGDFDEGP_02529,POPGJMOL_04348
BGDHLHFA_01349,DGDFDEGP_02811,POPGJMOL_04175
BGDHLHFA_01734,DGDFDEGP_04039,POPGJMOL_04234
BGDHLHFA_00509,DGDFDEGP_02546,POPGJMOL_00085
BGDHLHFA_04577,DGDFDEGP_04242,POPGJMOL_00124

각 열의 첫 번째 필드를 제외한 모든 열을 각 열의 첫 번째 필드 이름이 지정된 새 파일에 개별적으로 인쇄해야 합니다. 예상 출력은 다음과 같습니다.

피치시콜라19.txt

BGDHLHFA_02833
BGDHLHFA_01427
BGDHLHFA_01618
BGDHLHFA_01349
BGDHLHFA_01734
BGDHLHFA_00509
BGDHLHFA_04577

시시코라39.txt

DGDFDEGP_00879
DGDFDEGP_03106
DGDFDEGP_02529
DGDFDEGP_02811
DGDFDEGP_04039
DGDFDEGP_02546
DGDFDEGP_04242

12xRedbud.txt

POPGJMOL_04119
POPGJMOL_01558
POPGJMOL_04348
POPGJMOL_04175
POPGJMOL_04234
POPGJMOL_00085
POPGJMOL_00124

다음 명령을 사용하여 각 열을 인쇄할 수 있지만 awk -F "," '{print $1}' list.csv첫 번째 필드를 기반으로 파일을 저장하고 모든 새 파일에서 첫 번째 필드를 제거한다는 점에서 내 목적에 부합하지 않습니다. 이 프로세스를 자동화하도록 도와주세요. 미리 감사드립니다.

답변1

awk -F, 'NR==1{ split($0, tmp, ","); next }
              { for(col=1; col<=NF; col++){ print $col >>tmp[col]; close(tmp[col])} }' infile

존재하다NR==1{ split($0, tmp, ","); next }; NR어디총 대표자 수질소수량오른쪽첫 번째 행에 대해 지금까지 읽은/본 레코드입니다.NR1, 확인 중입니다NR==1, 그것이 첫 번째 라인이라면, 그 다음 블록이 실행될 것입니다.나뉘다()줄을 쉼표로 구분된 조각으로 나누고 ,해당 조각을 배열에 저장합니다 tmp. 그리고 next줄을 읽습니다.

두 번째 블록에서는 루프를 돌립니다.질소수량에프현재 입력 레코드의 필드를 검색하고 해당 열을 $col배열의 관련 파일 이름 tmp에 인쇄(추가)합니다.열쇠열 번호와 동일합니다.

답변2

시스템이 한 번에 프로세스를 열 수 있도록 허용하는 최대값(또는 그보다 적으면 awk)을 초과할 만큼 충분한 열이 있는 경우 GNU awk를 사용하여 많은 수의 열린 파일을 관리합니다.

$ cat tst.awk
BEGIN { FS="," }
NR==1 {
    for (i=1; i<=NF; i++) {
        out[i] = $i ".txt"
    }
    next
}
{
    for (i=1; i<=NF; i++) {
        print $i > out[i]
    }
}

$ awk -f tst.awk list.csv

$ head *.txt
==> 12xbauhiniae.txt <==
POPGJMOL_04119
POPGJMOL_01558
POPGJMOL_04348
POPGJMOL_04175
POPGJMOL_04234
POPGJMOL_00085
POPGJMOL_00124

==> Pcissicola19.txt <==
BGDHLHFA_02833
BGDHLHFA_01427
BGDHLHFA_01618
BGDHLHFA_01349
BGDHLHFA_01734
BGDHLHFA_00509
BGDHLHFA_04577

==> cissicola39.txt <==
DGDFDEGP_00879
DGDFDEGP_03106
DGDFDEGP_02529
DGDFDEGP_02811
DGDFDEGP_04039
DGDFDEGP_02546
DGDFDEGP_04242

그렇지 않으면 awk를 사용하여 원하는 수의 열을 처리하십시오.

$ cat tst.awk
BEGIN { FS="," }
NR==1 {
    for (i=1; i<=NF; i++) {
        out[i] = $i ".txt"
        printf "" > out[i]
        close(out[i])
    }
    next
}
{
    for (i=1; i<=NF; i++) {
        print $i >> out[i]
        close(out[i])
    }
}

답변3

또는 사용 bashcuttr

#!/bin/bash

id=0
while read filename; do
  id=$((id+1))
  tail -n +2 list | cut -d"," -f $id >> "$filename"
done < <(head -1 list.csv | tr "," "\n")

답변4

  • 조합하여 사용할 수 있습니다.세게 때리다그리고:

    for n in 1 2 3; do awk -F "," "{if (NR!=1) {print \$$n}}" list.scv > $(awk -F "," "{if (NR==1) {print \$$n}}" list.scv) ; done
    
  • 예: 여기에 이미지 설명을 입력하세요.

관련 정보