Mengubah entri terakhir dalam daftar yang dibatasi koma

8

Saya memiliki file teks besar yang terlihat seperti ini:

36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,3
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,8
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,14
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,12

Output yang diinginkan adalah ini:

36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-03
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-08
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-14
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,MI-12

Saya telah mencoba posting lain yang relevan di sini dan di komunitas lain tetapi tidak bisa mendapatkan apa yang saya inginkan.

MEMPERBARUI

Ini adalah pertanyaan silang (saya ingin jawaban Unix / perl dan solusi batch / powershell untuk ini.) Yang memiliki jawaban menarik.

M--
sumber

Jawaban:

14

pendekatan awk denganfungsi sprintf (untuk menambahkan angka nol di depan):

awk -F, -v OFS=',' '$8=sprintf("MI-%02d",$8);' file

Hasil:

36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-03
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-08
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-14
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,MI-12

-F,- set koma ,sebagai pemisah bidang

$8 - menunjuk ke bidang kedelapan

%02d- format yang memperlakukan argumen fungsi sebagai angka 2- digit


Catatan , bidang terakhir dalam catatan dapat disajikan oleh$NF.

NF adalah variabel yang sudah ditentukan sebelumnya yang nilainya adalah jumlah bidang dalam catatan saat ini

Jadi, $NFsama dengan $8(untuk masukan Anda)

awk -F, -v OFS=',' '$(NF)=sprintf("MI-%02d", $(NF))' file
RomanPerekhrest
sumber
1
Sebuah kata peringatan (tidak relevan dalam contoh ini, tetapi dapat diterapkan dalam kasus lain): mengubah nilai salah satu bidang (di sini: $ 8) "menghitung ulang" bidang seluruh baris, dan memiliki efek samping: mis1: kehilangan beberapa pemisah ': echo "1   2 3    4" | awk '{$2=$2;print $0}'memberi: 1 2 3 4(hanya 1 spasi (atau OFS) yang tersisa di antara bidang). ex2) echo "1,,,2,3,,,,4" | awk -F',' '{$2=$2;print $0}'memberi: 1   2 3    4(koma menjadi spasi). Mungkin ada efek samping lain. Uji dan ambil pendekatan lain (gsub pada salinan variabel $ 0, misalnya) jika menentukan bidang memiliki efek samping yang merugikan.
Olivier Dulac
3

Anda dapat mencoba menggunakan awk:

awk 'BEGIN { FS = OFS = "," } { $NF = sprintf("MI-%02d", $NF); } 1' file
taliezin
sumber
2

Inilah solusi perl:

$ perl -F',' -lane '$last=$#F;$F[$last]=sprintf("MI-%02d",$F[$last]);print join ",", @F' input.txt                                       
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-03
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-08
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-14
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,MI-12

The -abendera memungkinkan kita untuk memperlakukan input sebagai array, berdasarkan pemisah ditentukan dengan -F. Pada dasarnya kami mengubah item terakhir dalam array itu, dan membangunnya kembali melalui joinperintah.

Sergiy Kolodyazhnyy
sumber
Terima kasih atas jawaban Anda. Memang membantu jika seseorang membutuhkan perl tetapi masih sprintfmerupakan ide inti dari jawaban Anda. Tidak seperti jika itu tidak benar, hanya saja tidak menawarkan sesuatu yang berbeda dari jawaban yang diterima. +1 lagian.
M--
1
@Masoud yah, alasan utama di sini adalah karena sprintf()digunakan secara khas saat menulis string format tertentu ke variabel, itulah sebabnya mengapa digunakan dalam banyak bahasa lain. Saya bisa menulis dengan Python juga - Python tidak punya sprintf()tapi ide inti akan tetap sama - menulis string yang diformat ke variabel. Atau, kami dapat beroperasi pada item array secara langsung dan hanya mencetaknya. Dengan jenis pertanyaan ini ada sejumlah solusi yang terbatas, pada dasarnya adalah apa yang saya coba katakan
Sergiy Kolodyazhnyy
1

Dengan input data seperti:

36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,3  
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,8  
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,14  
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,12  

di text.csv

kode di bawah ini

awk -F"," '{ i = 0;
  MyOutLine = "";
  j = NF - 1;
  while ( i < j ) {
    i++;
    MyOutLine = MyOutLine""$i",";
  }
  i++;
  x = sprintf( "%.2i", $i );
  y = "MI-"x;
  MyOutLine = MyOutLine""y;
  print MyOutLine; }' ./text.csv  

menghasilkan output seperti:

36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-03
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-08
36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-14
36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,MI-12
Norma
sumber
1

Tcl

Berikut ini adalah solusi saya, selesai menggunakan Tcl yang membaca dari file input.csv dan meletakkan hasilnya dalam file output.csv

set in [open input.csv]
set out [open output.csv w]

while {![eof $in]} {
   set line [gets $in]
   set last_comma_pos [string last , $line]
   puts $out [string range $line 0 $last_comma_pos][format MI-%02d [string range $line $last_comma_pos+1 end]]
}

close $in
close $out

demonstrasi

sergiol
sumber