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すると、シェルから変数を読み込むことができます。この場合、date +"Y"単に現在の年を返します。フィールドを分割できる機能がありますawksplitこの場合、日付を含む4番目のフィールドは/、月/日/年を区切ります。split物事を配列に分割します。この場合、配列に名前を付けましたdob(生年月日)。3番目のフィールド(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
   }

}

別の方法として、シェルの日付への外部呼び出しとそれに続く getline を使用しない @steve のソリューションは次のようになります。

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
    }
}

年間秒数の概算を使用したくなかったので、それが機能しないエッジケースがあると思うので、そのルートには行きませんでした。@steve のオリジナルのように、上記の最初のソリューションで行ったように、入力年に欠落している世紀を提供するために、上記の 2 番目のソリューションを変更する必要があります。

于 2012-10-22T14:25:44.283 に答える