Jika saya memiliki file csv, apakah ada cara bash cepat untuk mencetak konten dari satu kolom saja? Dapat diasumsikan bahwa setiap baris memiliki jumlah kolom yang sama, tetapi setiap konten kolom akan memiliki panjang yang berbeda.
111
echo '1,"2,3,4,5",6' | awk -F "\"*,\"*" '{print $2}'
akan mencetak2
alih-alih2,3,4,5
.gawk -F"|" "{print $13}" files*.csv
...,"string,string",...
"
dan terakhir akan diakhiri dengan"
awk -F "\"*;\"*" '{print $2}' textfile.csv
Iya.
cat mycsv.csv | cut -d ',' -f3
akan mencetak kolom ke-3.sumber
awk
Cara paling sederhana saya bisa menyelesaikan ini adalah dengan hanya menggunakan csvtool . Saya memiliki kasus penggunaan lain juga untuk menggunakan csvtool dan dapat menangani tanda kutip atau pembatas dengan tepat jika muncul dalam data kolom itu sendiri.
Mengganti 2 dengan nomor kolom akan secara efektif mengekstrak data kolom yang Anda cari.
sumber
cat input.csv | csvtool formath '%(2)\n' -
Catatan Saya tahu cat di sini tidak berguna tetapi sub untuk perintah apa pun yang biasanya mengekspor csv.format '%(2)\n'
perintah tidak dapat memberi tahu di mana satu bidang berakhir. (csvtool 1.4.2)csvtool
tampaknya perlu digunakan-
sebagai nama file masukan untuk membaca dari stdin.csvtool format '%(1),%(10)\n' - < in.csv > out.csv
Mendarat di sini mencari untuk mengekstrak dari file yang dipisahkan tab. Pikir saya akan menambahkan.
Di mana
-f2
mengekstrak 2, kolom yang diindeks bukan nol, atau kolom kedua.sumber
cat
tidak perlu:< textfile.tsv cut -f2 -s
Banyak jawaban untuk pertanyaan-pertanyaan ini bagus dan beberapa bahkan telah menyelidiki kasus-kasus sudut. Saya ingin menambahkan jawaban sederhana yang dapat digunakan sehari-hari ... di mana Anda kebanyakan masuk ke kasus sudut tersebut (seperti tidak menggunakan koma atau koma dalam tanda kutip dll,).
Jadi dengan menggunakan BEGIN (Execute before taking input) kita dapat mengatur field ini menjadi apapun yang kita inginkan ...
Kode di atas akan mencetak kolom ke-3 di file csv.
sumber
Jawaban lain berfungsi dengan baik, tetapi karena Anda meminta solusi hanya dengan menggunakan bash shell, Anda dapat melakukan ini:
Dan kemudian Anda dapat menarik kolom (yang pertama dalam contoh ini) seperti ini:
Jadi ada beberapa hal yang terjadi di sini:
while IFS=,
- Ini berarti menggunakan koma sebagai IFS (Internal Field Separator), yang digunakan shell untuk mengetahui apa yang memisahkan bidang (blok teks). Jadi mengatakan IFS =, seperti mengatakan "a, b" sama dengan "a b" akan menjadi jika IFS = "" (yang secara default.)read -a csv_line;
- ini mengatakan membaca di setiap baris, satu per satu dan membuat larik di mana setiap elemen disebut "csv_line" dan mengirimkannya ke bagian "lakukan" di loop sementara kamido echo "${csv_line[0]}";done < file
- sekarang kita berada dalam fase "lakukan", dan kita mengatakan echo elemen ke 0 dari array "csv_line". Tindakan ini diulangi di setiap baris file. Bagian< file
ini hanya memberi tahu loop while dari mana harus membaca. CATATAN: ingat, dalam bash, array diindeks 0, jadi kolom pertama adalah elemen ke-0.Jadi begitulah, menarik kolom dari CSV di shell. Solusi lain mungkin lebih praktis, tetapi yang ini murni pesta.
sumber
Anda dapat menggunakan GNU Awk, lihat artikel panduan pengguna ini . Sebagai peningkatan solusi yang disajikan dalam artikel (pada bulan Juni 2015), perintah gawk berikut memungkinkan tanda kutip ganda di dalam bidang tanda kutip ganda; kutipan ganda ditandai dengan dua tanda kutip ganda berturut-turut ("") di sana. Selain itu, ini memungkinkan bidang kosong, tetapi ini pun tidak dapat menangani bidang multiline . Contoh berikut mencetak kolom ke-3 (melalui
c=3
) dari textfile.csv:Catat penggunaan dari
dos2unix
untuk mengkonversi kemungkinan jeda baris gaya DOS (CRLF yaitu "\ r \ n") dan pengkodean UTF-16 (dengan tanda urutan byte), masing-masing menjadi "\ n" dan UTF-8 (tanpa tanda urutan byte). File CSV standar menggunakan CRLF sebagai pemisah baris, lihat Wikipedia .Jika masukan mungkin berisi bidang multiline, Anda dapat menggunakan skrip berikut. Perhatikan penggunaan string khusus untuk memisahkan rekaman dalam output (karena baris baru pemisah default dapat terjadi dalam rekaman). Sekali lagi, contoh berikut mencetak kolom ke-3 (melalui
c=3
) dari textfile.csv:Ada pendekatan lain untuk masalah tersebut. csvquote dapat menampilkan konten file CSV yang dimodifikasi sehingga karakter khusus di dalam bidang diubah sehingga alat pengolah teks Unix biasa dapat digunakan untuk memilih kolom tertentu. Misalnya kode berikut mengeluarkan kolom ketiga:
csvquote
dapat digunakan untuk memproses file besar yang sewenang-wenang.sumber
Berikut adalah contoh file csv dengan 2 kolom
Untuk mendapatkan kolom pertama, gunakan:
f adalah singkatan dari Field dan d adalah singkatan dari delimiter
Menjalankan perintah di atas akan menghasilkan keluaran sebagai berikut.
Keluaran
Untuk mendapatkan kolom ke-2 saja:
Dan di sini adalah output output
Kasus penggunaan lain:
File input csv Anda berisi 10 kolom dan Anda menginginkan kolom 2 hingga 5 dan kolom 8, menggunakan koma sebagai pemisah ".
cut menggunakan -f (artinya "kolom") untuk menentukan kolom dan -d (artinya "pembatas") untuk menentukan pemisah. Anda perlu menentukan yang terakhir karena beberapa file mungkin menggunakan spasi, tab, atau titik dua untuk memisahkan kolom.
cut adalah utilitas perintah dan berikut beberapa contoh lainnya:
sumber
Saya membutuhkan penguraian CSV yang tepat, bukan
cut
/awk
dan doa. Saya mencoba ini di mac tanpacsvtool
, tetapi mac memang dilengkapi dengan ruby, jadi Anda dapat melakukan:sumber
Pertama kita akan membuat CSV dasar
Kemudian kita mendapatkan kolom pertama
sumber
dengan 2 adalah kolom yang Anda minati
Anda juga bisa melakukannya
untuk melakukan banyak kolom
sumber
Saya pikir yang paling mudah adalah menggunakan csvkit :
Mendapatkan kolom ke-2:
csvcut -c 2 file.csv
Namun, ada juga csvtool , dan mungkin sejumlah alat bash csv lain di luar sana:
sudo apt-get install csvtool
(untuk sistem berbasis Debian)Ini akan mengembalikan 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 melepaskan baris header:
csvtool col 4 csv_file.csv | sed '1d'
sumber
Saya bertanya-tanya mengapa sejauh ini tidak ada jawaban yang menyebutkan csvkit.
dokumentasi csvkit
Saya menggunakannya secara eksklusif untuk manajemen data csv dan sejauh ini saya belum menemukan masalah yang tidak dapat saya selesaikan menggunakan cvskit.
Untuk mengekstrak satu atau lebih kolom dari file cvs Anda dapat menggunakan
csvcut
utilitas yang merupakan bagian dari toolbox. Untuk mengekstrak kolom kedua gunakan perintah ini:halaman referensi csvcut
Jika string di csv dikutip, tambahkan karakter kutipan dengan
q
opsi:Pasang dengan
pip install csvkit
atausudo apt install csvkit
.sumber
Anda tidak dapat melakukannya tanpa pengurai CSV lengkap.
sumber
cut
dihitung?Telah menggunakan kode ini untuk sementara waktu, ini tidak "cepat" kecuali Anda menghitung "memotong dan menempel dari stackoverflow".
Ini menggunakan operator $ {##} dan $ {%%} dalam satu loop, bukan IFS. Ini memanggil 'err' dan 'die', dan hanya mendukung koma, tanda hubung, dan pipa sebagai karakter SEP (hanya itu yang saya butuhkan).
Contoh:
sumber
Anda juga dapat menggunakan while loop
sumber