我在创建 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-工具