Apakah ada mantra baris perintah untuk menjatuhkan kolom dalam file CSV?

32

Memiliki file dari konten berikut:

1111,2222,3333,4444
aaaa,bbbb,cccc,dddd

Saya berusaha mendapatkan file yang sama dengan aslinya tetapi tidak memiliki kolom ke-n seperti, untuk n = 2 (atau mungkin 3)

1111,2222,4444
aaaa,bbbb,dddd

atau, untuk n = 0 (atau mungkin 1)

2222,3333,4444
bbbb,cccc,dddd

File asli bisa panjang gigabita memiliki puluhan ribu kolom.

Seperti biasa dalam kasus seperti itu, saya menduga penyihir baris perintah dapat menawarkan solusi yang elegan ... :-)

Dalam kasus saya yang sebenarnya saya perlu menjatuhkan 2 kolom pertama, yang dapat dilakukan dengan menjatuhkan kolom pertama dua kali secara berurutan, tapi saya kira akan lebih menarik untuk menggeneralisasi sedikit.

Ivan
sumber
Apakah bidang dijamin tidak mengandung ,? (Yaitu, ,hanya pernah digunakan sebagai pemisah lapangan.)
CVn
@ MichaelKjörling, akan menyenangkan untuk memiliki solusi yang lebih fleksibel, tetapi dalam kasus saya - ya: pemisahnya ,dan tidak pernah terjadi di dalam bidang.
Ivan
Dalam hal ini, jawaban Scott seharusnya tepat.
CVn

Jawaban:

47

Saya percaya ini khusus untuk memotong dari GNU coreutils:

$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd

Biasanya Anda menentukan bidang yang Anda inginkan melalui -f, tetapi dengan menambahkan --complement Anda membalikkan artinya, secara alami. Dari 'man cut':

--complement
    complement the set of selected bytes, characters or fields

Satu peringatan: jika salah satu kolom berisi koma, itu akan memotong, karena potong bukan pengurai CSV dengan cara yang sama seperti spreadsheet. Banyak parser memiliki gagasan berbeda tentang cara menangani pelolosan koma di CSV. Untuk kasus CSV sederhana, pada baris perintah, cut masih merupakan jalan yang harus ditempuh.

Scott McClung
sumber
4
Itu berfungsi dengan baik selama itu file CSV sederhana. Jika salah satu kolom adalah string dengan koma di dalamnya, itu akan dibuang cutkarena itu bukan parser CSV. Jika bidang CSV memiliki pemisah bidang dalam nilainya, bidang itu dibungkus dengan tanda kutip. Btw, pada subjek cut, -fmengambil rentang bidang. cut -f, -d3-akan menampilkan bidang ketiga aktif, menghapus dua yang pertama.
Alexios
2
Maksud Andacut -d, -f3-
Useless
@ Alexios itu poin yang bagus. Saya tidak pernah benar-benar berurusan dengan CSV "asli", hanya bagian sederhana. Saya akan mengedit jawaban saya untuk mencerminkan itu.
Scott McClung
@Useless: Sial, ya. Itulah yang saya sebut 'potong disleksia' saya menyerang lagi. desah . Scott: File CSV adalah binatang yang sulit. Terlalu banyak sub-format yang berbeda, beberapa di antaranya bahkan bukan C SV, tetapi disebut demikian pula.
Alexios
Ini mencetak CSV baru ke terminal saya - bagaimana cara mendapatkannya untuk menimpa input (atau mungkin menulis ke file baru, sepertinya OP juga mencari)?
Max Ghenis
12

Jika data hanya terbuat dari kolom yang dipisahkan koma:

cut -d , -f 1-2,4-

Anda juga dapat menggunakan awk, tetapi agak canggung karena saat membersihkan bidang mudah, menghapus separator membutuhkan kerja. Jika Anda tidak memiliki bidang kosong, itu tidak terlalu buruk:

awk -F , 'BEGIN {OFS=FS}  {$3=""; sub(",,", ","); print}'

Jika Anda memiliki CSV aktual, di mana koma dapat muncul di dalam bidang jika dikutip dengan benar, Anda memerlukan pustaka CSV nyata .

Gilles 'SANGAT berhenti menjadi jahat'
sumber