Bash script / awk untuk memasukkan dan mengeluarkan file CSV

Sep 28 2020

Saya mengalami masalah dalam membuat skrip bash / awk / sed yang akan mengambil file CSV yang dipisahkan koma dari tiga kolom (nama depan, nama belakang, tanggal lahir), dan mengeluarkan file CSV lain yang memiliki kolom yang sama dari masukan dengan kolom tambahan yang menunjukkan perbedaan antara tanggal sekarang dan tanggal lahir dalam tahun.

$ yourscript <input CSV file> <output CSV file>

input.csv mungkin terlihat seperti ini:

bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

output.csv akan terlihat seperti ini:

bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48

Jawaban

3 Cbhihe Sep 28 2020 at 14:46
$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

Untuk mengeluarkan file bernama output-filedan ditampilkan ke STDOUT pada saat bersamaan:

$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data | tee output-file
bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48

Atau hanya menampilkan ke file yang sama:

$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data > output-file
2 Cbhihe Sep 30 2020 at 18:04

Untuk melakukan perhitungan waktu yang lebih akurat, Anda bisa menggunakan gawk's waktu dan fungsi string (per @ saran AdminBee ini). Menggunakan data masukan sebagai:

$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

Anda bisa mendapatkan perbedaan waktu dalam hari antara sekarang dan tanggal yang ditampilkan di setiap baris, dengan:

$ awk -F, 'BEGIN{today=systime()} 
           {print $0 "," int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))}' \
           data | tee output-file

 bob,wag,06/13/1958,22755
 ashley,hay,01/23/1983,13765
 evan,bert,09/11/1972,17551

Potongannya:

int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))

melakukan tiga hal dasar untuk setiap baris file input:

  • itu menghitung waktu yang telah berlalu (dalam detik) sejak 1970-01-01 00:00:00 UTC (pada sistem POSIX), tidak menghitung detik kabisat, dengan mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00)
  • itu menghitung perbedaan waktu antara kuantitas di atas dan variabel today, yang berisi jumlah detik yang telah berlalu pada waktu eksekusi sejak 1970-01-01 00:00:00 UTC.
  • itu membagi perbedaan waktu dalam detik dengan 3600 * 24 untuk mendapatkan hari yang sama, dan hanya mempertimbangkan bagian bilangan bulat dari hasil, untuk mendapatkan hari penuh int().

Anda dapat memainkannya untuk mendapatkan perbedaan waktu Anda dalam hitungan detik, menit, jam sesuai kebutuhan Anda. HTH

MaheshK. Sep 28 2020 at 11:49

Untuk mendapatkan perbedaan tanggal, Anda dapat menggunakan fungsi pesta kecil ini

Gunakan nomor berikut untuk kebutuhan Anda

  • #Untuk mendapatkan perbedaan Hari : 86400
  • #Untuk mendapatkan perbedaan Tahun : 31536000

Fungsi Bash

datediff() {
  current_date=$(date -d "$1" +%s)
  birth_date=$(date -d "$2" +%s)
  echo $(( (current_date - birth_date) / 31536000)) Years
}

Pemakaian:

datediff '9/28/2020' '1/1/1999'

Keluaran:

 21 years
MarcinŚlusarz Jan 09 2021 at 09:58

Bergantung pada apa yang Anda inginkan:

perbedaan tahun:

(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite \
 "select *, strftime('%Y', 'now') - substr(d, 7, 4) as year_diff
  from input" | csv-header --remove

usia:

(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite
  "select *, strftime('%Y', 'now') - substr(d, 7, 4) -
             case when strftime('%m%d', 'now') >= (substr(d, 1, 2) || substr(d, 4, 2))
             then 0 else 1 end as age
  from input" | csv-header --remove

csv-sqlite dan csv-header berasal dari csv-nix-tools