Bash 脚本/awk 输入和输出 CSV 文件

Bash 脚本/awk 输入和输出 CSV 文件

我在创建 bash/awk/sed 脚本时遇到了一些麻烦,该脚本将采用逗号分隔的三列(名字、姓氏、出生日期)的 CSV 文件,并输出另一个 CSV 文件,该文件具有与输入相同的列附加列显示当前日期和出生日期之间的差异(以年为单位)。

$ yourscript <input CSV file> <output CSV file>
  • input.csv可能看起来像这样:
    bob,wag,06/13/1958
    ashley,hay,01/23/1983
    evan,bert,09/11/1972
    
  • output.csv应该看起来像这样:
    bob,wag,06/13/1958,62
    ashley,hay,01/23/1983,37
    evan,bert,09/11/1972,48
    

答案1

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

要输出到名为的文件中output-file并同时显示到 STDOUT:

$ 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

或者只是输出到同一个文件:

$ awk -v year="$(\date +%Y)" 'BEGIN{FS="/"} {print $0 "," year-$3}' data > output-file

答案2

要执行更准确的时间计算,您可以使用gawk's时间和字符串函数(根据@AdminBee的建议)。使用输入数据作为:

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

您可以获得时差从现在到每行显示的日期,其中:

$ 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

片段:

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

为输入文件的每一行执行三项基本操作:

  • 它计算自 1970-01-01 00:00:00 UTC(在 POSIX 系统上)以来经过的时间(以秒为单位),不计算闰秒,mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00)
  • 它计算上述数量与变量 之间的时间差today,该变量包含自 1970-01-01 00:00:00 UTC 以来执行时经过的秒数。
  • 它将以秒为单位的时间差除以 3600*24 得到相同的天数,并且只考虑结果的整数部分,得到整天数int()

您可以根据需要使用它来获得以秒、分钟、小时为单位的时差。华泰

答案3

要获得日期差异,您可以使用这个小 bash 函数

使用以下数字满足您的需求

  • #要得到差价:86400
  • #要得到差值:31536000

bash 函数

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

用法:

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

输出:

 21 years

答案4

取决于你真正想要的:

年差:

(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

年龄:

(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 和 csv-header 来自csv-nix-工具

相关内容