Cara mengekstrak satu kolom dari file csv

Jika saya memiliki file csv, ada bash cepat cara untuk mencetak isi dari hanya salah satu kolom? Ini adalah aman untuk mengasumsikan bahwa setiap baris memiliki jumlah kolom yang sama, tetapi masing-masing kolom's konten akan memiliki panjang yang berbeda.

Larutan

Anda bisa menggunakan awk untuk ini. Perubahan '$2' untuk kesekian kolom yang anda inginkan.

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

ya. cat mycsv.csv | cut-d ',' -f3 akan mencetak 3 kolom.

Komentar (3)

Cara paling mudah saya bisa mendapatkan ini dilakukan adalah untuk hanya menggunakan csvtool. Saya punya kasus penggunaan lainnya juga untuk menggunakan csvtool dan dapat menangani kutipan atau pembatas tepat jika mereka muncul dalam kolom data itu sendiri.

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

Mengganti 2 dengan jumlah kolom akan secara efektif ekstrak data kolom yang anda cari.

Komentar (4)

Mendarat di sini mencari untuk mengekstrak dari tab file dipisahkan. Pikir saya akan menambahkan.

cat textfile.tsv | cut -f2 -s

Di mana -f2 ekstrak 2, kamar non-nol diindeks kolom, atau kolom kedua.

Komentar (3)

Banyak jawaban untuk pertanyaan ini adalah besar dan beberapa bahkan melihat ke sudut kasus. Saya ingin menambahkan jawaban sederhana yang dapat digunakan sehari-hari... di mana sebagian besar anda bisa menjadi orang-orang corner kasus (seperti setelah lolos koma atau koma dalam kutipan dll.,).

FS (Field Separator) adalah variabel yang nilainya dafaulted untuk ruang. Jadi awk secara default perpecahan di ruang untuk setiap baris.

Jadi menggunakan BEGIN (Mengeksekusi sebelum mengambil input) kita dapat mengatur bidang ini untuk apa pun yang kita inginkan...

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

Kode di atas akan mencetak 3 kolom di file csv.

Komentar (1)

Dengan jawaban yang lain bekerja dengan baik, tetapi karena anda diminta untuk solusi hanya menggunakan bash shell, anda dapat melakukan ini:

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

Dan kemudian anda dapat menarik keluar kolom (pertama dalam contoh ini) seperti:

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

Jadi ada's beberapa hal yang terjadi di sini:

  • sementara IFS=, - ini mengatakan untuk menggunakan koma sebagai IFS (Internal Field Separator), yang adalah apa yang shell menggunakan untuk tahu apa yang memisahkan bidang (blok teks). Jadi mengatakan IFS=, seperti mengatakan "b" adalah sama dengan "b" akan jika IFS=" " (yang ini apa yang itu adalah secara default.)

  • baca-csv_line; - ini mengatakan baca di setiap baris, satu pada satu waktu dan membuat array di mana masing-masing elemen ini disebut "csv_line" dan mengirim bahwa untuk "tidak" bagian dari while loop

  • echo "${csv_line[0]";selesai < file - sekarang kita're di "tidak" fase, dan kami're mengatakan echo elemen 0 array "csv_line". Tindakan ini diulang pada setiap baris dari file. The < file bagian ini hanya menceritakan sementara lingkaran di mana untuk membaca dari. CATATAN: ingat, di bash, array adalah 0 diindeks, sehingga kolom pertama adalah elemen 0.

Jadi di sana anda memilikinya, menarik keluar sebuah kolom dari sebuah CSV in the shell. Solusi lain yang mungkin lebih praktis, tapi yang satu ini adalah murni bash.

Komentar (0)

Anda bisa menggunakan GNU Awk, lihat [artikel ini dari user guide][1]. Sebagai perbaikan untuk solusi yang disajikan dalam artikel (juni 2015), berikut melongo perintah yang memungkinkan tanda kutip ganda dalam dua dikutip sawah; double quote ditandai dengan dua tanda kutip ganda ("") ada. Selain itu, hal ini memungkinkan bidang-bidang kosong, tapi ini bahkan tidak bisa menangani multiline bidang. Berikut contoh cetakan ke-3 kolom (via c=3) dari 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 < 
Komentar (0)

[bodoh@satu pts]$ cat > file #Pertama kita'll membuat dasar 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

[bodoh@satu pts]$ awk -F , '{print $1}' file a Satu a Satu

Komentar (0)

Aku butuh yang tepat CSV parsing, tidak cut / awk dan doa. I'm mencoba ini di mac tanpa csvtool, tapi mac tidak datang dengan ruby, sehingga anda dapat melakukan:

echo "require 'csv'; CSV.read('new.csv').each {|data| puts data[34]}" | ruby
Komentar (0)
csvtool col 2 file.csv 

di mana 2 adalah kolom yang anda tertarik

anda juga dapat melakukan

csvtool col 1,2 file.csv 

untuk melakukan beberapa kolom

Komentar (0)

Saya pikir yang paling mudah adalah dengan menggunakan csvkit:

Mendapat 2 kolom: csvcut -c 2 file.csv

Namun, ada's juga csvtool, dan mungkin sejumlah lainnya csv bash alat-alat di luar sana:

sudo apt-get install csvtool (untuk Debian berbasis sistem)

Ini akan kembali kolom dengan baris pertama memiliki 'ID' di dalamnya. csvtool namedcol ID csv_file.csv

Ini akan mengembalikan baris keempat: csvtool col 4 csv_file.csv

Jika anda ingin drop baris header:

csvtool col 4 csv_file.csv | sed &#39;1d&#39;

Komentar (0)

Anda dapat't melakukan itu tanpa penuh CSV parser.

Komentar (1)

Aku bertanya-tanya mengapa tidak ada jawaban yang sejauh ini telah disebutkan csvkit.

csvkit adalah sebuah suite alat-alat baris perintah untuk mengkonversi ke dan bekerja dengan CSV

csvkit dokumentasi

Saya menggunakannya secara eksklusif untuk data csv manajemen dan sejauh ini saya belum menemukan masalah yang saya tidak bisa memecahkan menggunakan cvskit.

Untuk ekstrak satu atau lebih kolom dari cvs file, anda dapat menggunakan csvcut utilitas yang merupakan bagian dari toolbox. Untuk mengekstrak kolom kedua menggunakan perintah ini:

csvcut -c 2 filename_in.csv > filename_out.csv 

csvcut referensi halaman

Jika string di csv yang dikutip, tambahkan kutipan karakter dengan q pilihan:

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

Install dengan pip menginstal csvkit atau sudo apt-get install csvkit.

Komentar (0)

Berikut ini adalah file csv contoh dengan 2 kolom

myTooth.csv

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

Untuk mendapatkan kolom pertama, gunakan:

cut -d, -f1 myTooth.csv

f singkatan dari Lapangan dan d adalah singkatan dari pembatas

Menjalankan perintah di atas akan menghasilkan output sebagai berikut.

Output

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

Untuk mendapatkan kolom ke-2 saja:

cut -d, -f2 myTooth.csv

Dan di sini adalah output Output

Tooth
wisdom
canine
canine
wisdom
incisor

Use case lain:

Anda csv file input yang berisi 10 kolom dan anda ingin kolom 2 sampai 5 dan kolom 8, menggunakan koma sebagai pemisah".

potong menggunakan -f (arti "bidang") untuk menentukan kolom dan -d (yang berarti "pembatas") untuk menentukan pemisah. Anda perlu menentukan terakhir karena beberapa file mungkin menggunakan spasi, tab, atau titik dua untuk kolom yang terpisah.

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

cut adalah perintah utilitas dan berikut adalah beberapa contoh:

SYNOPSIS
     cut -b list [-n] [file ...]
     cut -c list [file ...]
     cut -f list [-d delim] [-s] [file ...]
Komentar (0)

Anda juga dapat menggunakan while loop


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

        echo Name: "$name"
done
Komentar (0)

Menggunakan kode ini untuk sementara, hal ini tidak "cepat" kecuali jika anda menghitung "memotong dan paste dari stackoverflow".

Menggunakan ${##} dan ${%%} operator di lingkaran bukan IFS. Itu panggilan 'err' dan 'mati', dan hanya mendukung koma, dash, dan pipa sebagai SEP karakter (yang's semua yang saya butuhkan).

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*}
}

Contoh:

$ 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
Komentar (0)