0

我有一个文本文件,其中包含以下格式的多个字段。姓名:电话:地址:出生日期:工资 出生日期的格式为 mm/dd/yy。我不知道如何通过从当年减去他们的出生年份来计算特定人的年龄。我需要提取年龄,然后将其与某个年龄组进行比较,比如 50 岁。我尝试了一些东西,但它给了我奇怪的数字,比如 awk -F: '{print $4-d}' "d=$(date)" filename

4

2 回答 2

1

您可能想尝试:

awk -F: -v year=$(date +"%Y") '{ split($4, dob, "/"); print $1, "is", year-dob[3], "years old" }' file.txt

编辑1:

要简单地打印 60 岁以下的人的列表,请尝试:

awk -F: -v year=$(date +"%Y") '{ split($4, dob, "/"); if (year-dob[3] <= 60) print $1 }' file.txt

解释:

我假设对awk. 该-v选项允许awk从 shell 中读取变量。在这种情况下,date +"Y"只需返回当前年份。awk具有split允许您拆分字段的功能。在这种情况下,包含我们日期的第四个字段/将月/日/年分开。split将事物拆分为数组。在本例中,我将数组命名为dob(出生日期)。第三个字段(索引 1)包含出生年份。然后在有条件的情况下进行一些快速数学运算,以检查该人的年龄是否为 60 岁以上。如果他在第一个字段中打印出他的名字。

编辑2:

再考虑一下您的问题后,很明显上述方法实际上并不能完美地计算事物。这是一项艰巨的快速工作(对不起,好吧......)。因此,这是一个更新版本,它将更加准确。像这样运行:

awk -f script.awk file.txt

内容script.awk

BEGIN {
    FS=":"
    "date +\"%s\"" | getline cdate
}

{
    rdate = gensub(/([0-9]+)\/([0-9]+)\/([0-9]+)/, "\\3-\\1-\\2", "g", $4)
    cmd = "date -d " rdate " +\"%s\""

    while (( cmd | getline result ) > 0 ) {

        if ((cdate - result) / 31556926 <= 60) {
            print $1
        }
    }
}

编辑3:

或者没有外部命令和 getline:

BEGIN {
    FS=":"
    cdate = systime()
}

{
    rdate = gensub(/([0-9]+)\/([0-9]+)\/([0-9]+)/, "\\3 \\1 \\2 0 0 0", "g", $4)
    result = mktime(rdate)

    if ((cdate - result) / 31556926 <= 60) {
       print $1
    }
}
于 2012-10-22T02:56:32.370 回答
1

使用 GNU awk(应该可以工作但未经测试,因为您没有提供任何示例输入和预期输出):

BEGIN{
   FS = ":"
   nowSecs  = systime()
   nowYear  = strftime("%Y",nowSecs)
   nowDay   = strftime("%j",nowSecs)
}

{
   # input date format is MM/DD/YY
   dobSpec = gensub(/([0-9]+)\/([0-9]+)\/([0-9]+)/, "\\3 \\1 \\2 0 0 0", "", $4)
   dobSecs = mktime("20" dobSpec)

   if ( (dobSecs > nowSecs) || (dobSecs < 0) ) {
      # guessed the wrong century so try again
      dobSecs = mktime("19" dobSpec)
   }

   dobYear = strftime("%Y",dobSecs)
   dobDay  = strftime("%j",dobSecs)

   diffYears = nowYear - dobYear
   diffDays  = nowDay  - dobDay

   age = diffYears + (diffDays >= 0 ? 1 : 0)

   if ( age < 60 ) {
      print
   }

}

作为替代方案,这是@steve 的解决方案在不使用外部调用 shell 日期和后续 getline 的情况下的样子:

BEGIN {
    FS=":"
    cdate = systime()
}

{
    rdate = gensub(/([0-9]+)\/([0-9]+)\/([0-9]+)/, "\\3 \\1 \\2 0 0 0", "g", $4)
    result = mktime(rdate)

    if ((cdate - result) / 31556926 <= 60) {
       print $1
    }
}

I didn't go that route as I didn't want to use the seconds-per-year approximation since I think there are edge cases where that wouldn't work. Like @steve's original, the second solution above will need to be modified to provide the missing century in the input year just like I did in my first solution above.

于 2012-10-22T14:25:44.283 回答