Saya memiliki file csv yang sangat besar. Bagaimana Anda menghapus yang terakhir ,
dengan sed (atau serupa)?
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0],
]
Output yang diinginkan
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]
Perintah sed berikut akan menghapus kejadian terakhir per baris, tetapi saya ingin per file.
sed -e 's/,$//' foo.csv
Ini juga tidak bekerja
sed '$s/,//' foo.csv
Jawaban:
Menggunakan
awk
Jika koma selalu di akhir baris kedua hingga terakhir:
Menggunakan
awk
danbash
Menggunakan
sed
Untuk OSX dan platform BSD lainnya, cobalah:
Menggunakan
bash
sumber
sed: 1: "x;${s/,$//;p;x}; 2,$ p": extra characters at the end of x command
sed
dan seringkali berbeda dengan cara yang halus. Saya tidak memiliki akses ke OSX untuk menguji ini, tapi tolong cobased -n -e x -e '${s/,$//;p;x;}' -e '2,$ p' input
Cukup Anda bisa mencoba perintah Perl one-liner di bawah ini.
Penjelasan:
,
Cocok dengan koma.(?!.*,)
Lookahead negatif menyatakan bahwa tidak akan ada koma setelah koma yang cocok. Jadi itu akan cocok dengan koma terakhir.s
Dan hal yang paling penting adalahs
pengubah DOTALL yang membuat titik untuk mencocokkan bahkan karakter baris baru juga.sumber
perl -0777 -pi -e 's/(.*),(.*?)/\1\2/s'
. Ini berhasil karena yang pertama.*
serakah, sedangkan yang kedua tidak.Itu harus menghapus hanya kejadian terakhir
,
dalam file input apa pun - dan itu masih akan mencetak yang,
tidak terjadi. Pada dasarnya, ini mendukung urutan garis yang tidak mengandung koma.Ketika bertemu koma, ia menukar buffer garis saat ini dengan buffer terus dan dengan cara itu secara bersamaan mencetak semua baris yang terjadi sejak koma terakhir dan membebaskan buffer penahannya.
Saya baru saja menggali file sejarah saya dan menemukan ini:
Sebenarnya cukup bagus. Ya, itu digunakan
eval
, tetapi tidak pernah melewati apa pun di luar referensi numerik ke argumennya. Itu membangunsed
skrip sewenang-wenang untuk menangani pertandingan terakhir. Saya akan menunjukkan kepada Anda:Yang mencetak berikut ini ke stderr. Ini adalah salinan
lmatch
input:eval
Subshell fungsi ed iterates melalui semua argumennya sekali. Ketika ia berjalan di atasnya mereka itu counter yang tepat tergantung pada konteks untuk setiap switch dan melompati banyak argumen untuk iterasi berikutnya. Sejak saat itu ia melakukan satu dari beberapa hal per argumen:$a
ke$o
.$a
ditugaskan berdasarkan nilai$i
yang bertambah dengan jumlah arg untuk setiap arg yang diproses.$a
ditugaskan salah satu dari dua nilai berikut:a=$((i+=1))
- ini diberikan jika salah satu opsi pendek tidak memiliki argumennya ditambahkan atau jika opsi itu panjang.a=$i#-?
- ini ditugaskan jika opsi adalah pendek dan tidak memiliki arg yang ditambahkan untuk itu.a=\${$a}${1:+$d\${$(($1))\}}
- Terlepas dari penugasan awal,$a
nilai selalu dibungkus dalam kurung dan - dalam-s
kasus - kadang-kadang$i
bertambah satu lagi dan bidang tambahan dibatasi ditambahkan.Hasilnya adalah bahwa
eval
tidak pernah melewati string yang mengandung sesuatu yang tidak diketahui. Setiap argumen baris perintah dirujuk dengan nomor argumen numeriknya - bahkan pembatas yang diekstraksi dari karakter pertama argumen pertama dan merupakan satu-satunya waktu Anda harus menggunakan karakter apa pun yang tidak terhindar. Pada dasarnya, fungsinya adalah generator makro - ia tidak pernah menginterpretasikan nilai argumen dengan cara khusus karenased
dapat (dan akan, tentu saja) dengan mudah mengatasinya ketika mem-parsing skrip. Alih-alih, itu hanya dengan bijaksana mengatur argumennya menjadi naskah yang bisa diterapkan.Berikut ini beberapa hasil debug fungsi di tempat kerja:
Dan
lmatch
dapat digunakan untuk dengan mudah menerapkan regex ke data setelah pertandingan terakhir dalam sebuah file. Hasil dari perintah yang saya jalankan di atas adalah:... yang, mengingat subset dari input file yang mengikuti terakhir kali
/^.0/
dicocokkan, menerapkan substitusi berikut:sdd&&&&d
- Mengganti$match
sendiri 4 kali.sd'dsqd4
- kutipan tunggal keempat mengikuti awal baris sejak pertandingan terakhir.sd"d\dqd2
- Dita, tetapi untuk tanda kutip ganda dan global.Jadi, untuk mendemonstrasikan bagaimana seseorang dapat menggunakan
lmatch
untuk menghapus koma terakhir dalam file:KELUARAN:
sumber
-m
pilihan dan membuatnya wajib, beralih ke beberapa argumen untuk kembali dan membalas-s
dan juga menerapkan penanganan pembatas yang tepat. Saya pikir ini anti peluru. Saya berhasil menggunakan spasi dan kutipan tunggal sebagai pembatas,Jika koma mungkin tidak ada di baris kedua hingga terakhir
Menggunakan
awk
dantac
:The
awk
perintah yang sederhana untuk melakukan substitusi pertama kalinya pola terlihat.tac
membalik urutan baris dalam file, sehinggaawk
perintah akhirnya menghapus koma terakhir .Saya sudah diberitahu itu
mungkin lebih efisien.
sumber
Jika Anda dapat menggunakan
tac
:sumber
lihat /programming/12390134/remove-comma-from-last-line
Ini bekerja untuk saya:
Cara terbaik saya adalah menghapus baris terakhir dan setelah menghapus koma, tambahkan char] lagi
sumber
Coba dengan di bawah ini
vi
:Penjelasan:
$-1
pilih baris kedua hingga terakhirs
menggantikan\(,\)\(\_s*]\)
temukan koma yang diikuti oleh]
dan dipisahkan oleh spasi atau baris baru\2
ganti dengan\(\_s*]\)
spasi atau baris baru diikuti oleh]
sumber
Coba dengan
sed
perintah di bawah ini .sumber