programing

csv 파일의 열 하나를 추출하는 방법입니다.

telecom 2023. 4. 25. 21:51
반응형

csv 파일의 열 하나를 추출하는 방법입니다.

csv 파일이 있는 경우 단일 열의 내용만 인쇄할 수 있는 빠른 bash 방법이 있습니까?각 행의 열 수는 동일하지만 각 열의 내용 길이는 서로 다르다고 가정하는 것이 좋습니다.

이거에 awk를 쓸 수 있어요.$2'를 원하는 n번째 열로 변경합니다.

awk -F "\"*,\"*" '{print $2}' textfile.csv

네. 네. 네.cat mycsv.csv | cut -d ',' -f3이겁니다.

가장 간단한 방법은 csvtool을 사용하는 것입니다.csvtool을 사용하기 위한 다른 사용 사례도 있습니다. csvtool은 따옴표 또는 구분 기호를 열 데이터 자체에 표시할 경우 적절하게 처리할 수 있습니다.

csvtool format '%(2)\n' input.csv

2를 열 번호로 바꾸면 찾고 있는 열 데이터가 효과적으로 추출됩니다.

탭으로 구분된 파일에서 추출하기 위해 이곳에 도착했습니다.덧붙이려고 했어요

cat textfile.tsv | cut -f2 -s

여기서 ★★★★★★★★★★★★★★★★★.-f2는 0이 아닌 2개의 인덱스 열 또는 두 번째 열을 추출합니다.

가장 쉬운 방법은 csvkit을 사용하는 것입니다.

두 번째 열(예: 째째::::::::::::::)을 가져옵니다.csvcut -c 2 file.csv

그러나 csvtool과 다른 여러 csv bash 툴도 있습니다.

sudo apt-get install csvtool데비안 기반 시스템의 경우)(데비안 기반 시스템)

이렇게 하면 첫 번째 행이 '열로 되어 있습니다'로 되어 있는 열이 됩니다.신분증이 들어있어요 csvtool namedcol ID csv_file.csv

이렇게 하면 네 번째 행이 나옵니다.csvtool col 4 csv_file.csv

헤더 행을 드롭하려면 다음과 같이 하십시오.

csvtool col 4 csv_file.csv | sed '1d'

다음은 2개의 열이 있는 csv 파일 예제입니다.

myTooth.csv

Date,Tooth
2017-01-25,wisdom
2017-02-19,canine
2017-02-24,canine
2017-02-28,wisdom

첫 번째 열을 가져오려면 다음을 사용합니다.

cut -d, -f1 myTooth.csv

f는 필드를 나타내고 d는 구분 기호를 나타냅니다.

위의 명령을 실행하면 다음과 같은 출력이 생성됩니다.

산출량

Date
2017-01-25
2017-02-19
2017-02-24
2017-02-28

두 번째 열만 가져오려면 다음과 같이 하십시오.

cut -d, -f2 myTooth.csv

출력은 다음과 같습니다.

Tooth
wisdom
canine
canine
wisdom
incisor

또 다른 사용 사례는 다음과 같습니다.

CSV 입력 파일에 10개의 열이 포함되어 있으며 쉼표를 구분 기호로 사용하여 2 ~ 5열과 8열을 사용하려고 합니다.

cut은 열을 지정하는 데 -f("필드"를 의미)를 사용하고 구분 기호를 지정하는 데 -d("필드"를 의미)를 사용합니다.일부 파일은 공백, 탭 또는 콜론을 사용하여 열을 분리할 수 있으므로 후자를 지정해야 합니다.

cut -f 2-5,8 -d , myvalues.csv

cut은 명령 유틸리티이며 다음은 몇 가지 예입니다.

SYNOPSIS
     cut -b list [-n] [file ...]
     cut -c list [file ...]
     cut -f list [-d delim] [-s] [file ...]

먼저 기본 CSV를 생성합니다.

[dumb@one pts]$ cat > file 
a,b,c,d,e,f,g,h,i,k  
1,2,3,4,5,6,7,8,9,10  
a,b,c,d,e,f,g,h,i,k  
1,2,3,4,5,6,7,8,9,10

그러면 첫 번째 열이 나옵니다.

[dumb@one pts]$  awk -F , '{print $1}' file  
a  
1  
a  
1

이 질문에 대한 많은 답변이 훌륭하고 일부는 코너 케이스까지 살펴봤습니다.일상적으로 유용하게 쓰일 수 있는 간단한 답변을 덧붙이겠습니다.쉼표 또는 따옴표 안에 쉼표가 있는 경우 등 주로 이러한 코너 케이스에 대해 설명합니다.

FS(필드 구분자)는 값이 공백인 변수입니다.따라서 기본적으로 모든 선에 대해 공간을 분할합니다.

따라서 BEGIN(입력하기 전에 실행)을 사용하여 이 필드를 원하는 대로 설정할 수 있습니다.

awk 'BEGIN {FS = ","}; {print $3}'

위 코드는 세 번째 열을 csv 파일로 인쇄합니다.

다른 답변은 잘 작동하지만 bash 셸만 사용하여 솔루션을 요청했으므로 다음과 같이 할 수 있습니다.

AirBoxOmega:~ d$ cat > file #First we'll create a basic CSV
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10

그런 다음 다음과 같이 열(이 예의 첫 번째 열)을 꺼낼 수 있습니다.

AirBoxOmega:~ d$ while IFS=, read -a csv_line;do echo "${csv_line[0]}";done < file
a
1
a
1
a
1
a
1
a
1
a
1

여기서 몇 가지 일이 일어나고 있습니다.

  • while IFS=,- 내부 필드 구분자(IFS)입니다. 내부 필드 구분자(IFS)입니다.이렇게 해서 'a,b'라고 합니다. IFS=" " " " " " ( " b ) 。

  • read -a csv_line; 이것은 각 행에서 한 번에 하나씩 읽고 각 요소가 "csv_line"이라고 불리는 배열을 만들고 "do"를 반복하는 동안 루프 - 의 "do" 섹션으로 보냅니다.

  • do echo "${csv_line[0]}";done < file- 이제 '실행' 단계에 있고, 배열 "csv_line"의 0번째 요소를 "csv_line" - "csv_line" "csv_line" 0번째 요소를 반향합니다이 작업은 파일의 모든 줄에서 반복됩니다.»는 다음과 같습니다.< file트 loop while loop。참고: bash에서는 배열이 0 인덱스되므로 첫 번째 열은 0번째 요소입니다.참고: bash에서는 배열이 0으로 인덱싱되므로 첫 번째 열이 0번째 요소가 됩니다.

셸의 CSV에서 열을 추출할 수 있습니다.다른 솔루션이 더 실용적일 수 있지만, 이 솔루션은 완전히 엉망입니다.

CSV 파싱이 아니라 CSV 이 필요했어요.cut/ / / / / / / / / / / / / / / / / / 。awk이겁니다.맥에서 시도해보죠csvtool, 맥에는 루비가 함께 제공되므로 다음을 수행할 수 있습니다

echo "require 'csv'; CSV.read('new.csv').each {|data| puts data[34]}" | ruby

GNU Awk를 사용할 수 있습니다. 사용자 가이드의 이 문서를 참조하십시오.2015년 6월 기사에 제시된 솔루션의 개선 사항으로, 다음 gawk 명령어는 큰따옴표 안에 큰따옴표를 넣을 수 있습니다. 큰따옴표는 두 개의 연속된 큰따옴표("")로 표시됩니다.또한필드를 허용하지만 이 필드도 여러 줄 필드를 처리할 수 없습니다.다음 예제에서는 세 번째 열을 인쇄합니다.c=3) 또는 textfile.csv:textfile.csv를 사용합니다.

#!/bin/bash
gawk -- '
BEGIN{
    FPAT="([^,\"]*)|(\"((\"\")*[^\"]*)*\")"
}
{
    if (substr($c, 1, 1) == "\"") {
        $c = substr($c, 2, length($c) - 2) # Get the text within the two quotes
        gsub("\"\"", "\"", $c)  # Normalize double quotes
    }
    print $c
}
' c=3 < <(dos2unix <textfile.csv)

사용법은 주의해 주세요.dos2unix가능한 DOS 스타일 줄 바꿈(CRLF)을 변환합니다."\r\n")과 UTF-16 인코딩(바이트 순서 표시 포함)을 각각 "\n"으로, UTF-8 인코딩(바이트 순서 표시 없음)으로 지정합니다.표준 CSV 파일은 줄 바꿈으로 CRLF를 사용합니다(Wikipedia 참조).

입력에 여러 줄 필드가 포함된 경우 다음 스크립트를 사용할 수 있습니다.레코드 내에서 기본 구분 줄 바꿈이 발생할 수 있으므로 출력에서 레코드를 구분하기 위해 특수 문자열을 사용하십시오.다시 한 번, 다음 예제에서는 세 번째 열을 인쇄합니다.c=3) 또는 textfile.csv:textfile.csv를 사용합니다.

#!/bin/bash
gawk -- '
BEGIN{
    RS="\0" # Read the whole input file as one record;
    # assume there is no null character in input.
    FS="" # Suppose this setting eases internal splitting work.
    ORS="\n####\n" # Use a special output separator to show borders of a record.
}
{
    nof=patsplit($0, a, /([^,"\n]*)|("(("")*[^"]*)*")/, seps)
    field=0;
    for (i=1; i<=nof; i++){
        field++
        if (field==c) {
            if (substr(a[i], 1, 1) == "\"") {
                a[i] = substr(a[i], 2, length(a[i]) - 2) # Get the text within 
                # the two quotes.
                gsub(/""/, "\"", a[i])  # Normalize double quotes.
            }
            print a[i]
        }
        if (seps[i]!=",") field=0
    }
}
' c=3 < <(dos2unix <textfile.csv)

이 문제에 대한 다른 접근 방법이 있습니다. csvquote는 필드 내의 특수 문자를 변환하여 일반적인 Unix 텍스트 처리 도구를 사용하여 특정 열을 선택할 수 있도록 수정된 CSV 파일의 내용을 출력할 수 있습니다.예를 들어, 다음 코드는 세 번째 열을 출력합니다.

csvquote textfile.csv | cut -d ',' -f 3 | csvquote -u

csvquote임의의 대용량 파일을 처리하는 데 사용할 수 있습니다.

왜 지금까지 어떤 답변도 csvkit에 대해 언급하지 않았는지 궁금합니다.

csvkit은 CSV로 변환하고 CSV로 작업하기 위한 명령줄 도구 모음입니다.

csvkit 설명서입니다.

CSV 데이터 관리 전용으로 사용하고 있으며, 현재까지 cvskit으로 해결할 수 없는 문제는 발견되지 않았습니다.

파일에서 을 하나 추출하려면 cvs 파일 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 음 the the the the the the the the the the the the the the 。csvcut이겁니다.두 번째 열을 추출하려면 다음 명령을 사용합니다.

csvcut -c 2 filename_in.csv > filename_out.csv 

csvcut 참조 페이지입니다.

이 따옴표로 묶인 csv에 따옴표를 추가합니다.q옵션을 선택합니다.

csvcut -q '"' -c 2 filename_in.csv > filename_out.csv 

함께 설치합니다.pip install csvkit아니면요?sudo apt install csvkit요.

csvtool col 2 file.csv 

여기서 2는 관심 있는 열입니다.

당신은 또한 할 수 있습니다.

csvtool col 1,2 file.csv 

여러 열을 수행합니다.

awk를 사용하여 간단하게 해결합니다."colNum" 대신 인쇄할 열 수를 입력합니다.

cat fileName.csv | awk -F ";" '{ print $colNum }'

전체 CSV 파서가 없으면 이 작업을 수행할 수 없습니다.

데이터가 인용되지 않을 것을 알고 있다면, 분할되는 솔루션은 다음과 같습니다.,잘될 것입니다(저는 손을 뻗는 경향이 있습니다).cut -d, -f1 | sed 1dCSV를 사용합니다.

다른 CSV xsv파일을 생성하려면 , , 를 사용하십시오.csvtoolCSV를 사용합니다.

CSV 파일의 단일 열 내용을 추출하여 후속 명령으로 처리할 수 있도록 따옴표를 해제하려는 경우, 이 Python 1-liner는 헤더가 있는 CSV 파일에 대해 다음과 같은 트릭을 수행합니다.

python -c 'import csv,sys'$'\n''for row in csv.DictReader(sys.stdin): print(row["message"])'

»는 다음과 같습니다."message"안쪽에 있습니다.print기능을 사용합니다.

CSV 파일에 헤더가 없는 경우 다음을 수행합니다.

python -c 'import csv,sys'$'\n''for row in csv.reader(sys.stdin): print(row[1])'

Python의 CSV 라이브러리는 모든 종류의 CSV 사투리를 지원하므로 CSV 파일에서 다른 규약을 사용하는 경우 코드를 거의 변경하지 않고도 이러한 사투리를 지원할 수 있습니다.

한동안 이 코드를 사용했지만 "stackoverflow에서 잘라내기 및 붙여넣기"를 세지 않으면 "빠르지 않습니다.

IFS 대신 루프에서 ${#} 및 ${%} 연산자를 사용합니다.'err' 및 'die'를 호출하고 쉼표, 대시 및 파이프만 SEP 문자로 지원합니다(이것만 있으면 됩니다).

err()  { echo "${0##*/}: Error:" "$@" >&2; }
die()  { err "$@"; exit 1; }

# Return Nth field in a csv string, fields numbered starting with 1
csv_fldN() { fldN , "$1" "$2"; }

# Return Nth field in string of fields separated
# by SEP, fields numbered starting with 1
fldN() {
        local me="fldN: "
        local sep="$1"
        local fldnum="$2"
        local vals="$3"
        case "$sep" in
                -|,|\|) ;;
                *) die "$me: arg1 sep: unsupported separator '$sep'" ;;
        esac
        case "$fldnum" in
                [0-9]*) [ "$fldnum" -gt 0 ] || { err "$me: arg2 fldnum=$fldnum must be number greater or equal to 0."; return 1; } ;;
                *) { err "$me: arg2 fldnum=$fldnum must be number"; return 1;} ;;
        esac
        [ -z "$vals" ] && err "$me: missing arg2 vals: list of '$sep' separated values" && return 1
        fldnum=$(($fldnum - 1))
        while [ $fldnum -gt 0 ] ; do
                vals="${vals#*$sep}"
                fldnum=$(($fldnum - 1))
        done
        echo ${vals%%$sep*}
}

예를 들어 다음과 같습니다.

$ CSVLINE="example,fields with whitespace,field3"
$ $ for fno in $(seq 3); do echo field$fno: $(csv_fldN $fno "$CSVLINE");  done
field1: example
field2: fields with whitespace
field3: field3

while loop을 사용할 수도 있습니다.

IFS=,
while read name val; do
        echo "............................"

        echo Name: "$name"
done<itemlst.csv

언급URL : https://stackoverflow.com/questions/19602181/how-to-extract-one-column-of-a-csv-file 입니다.

반응형