2012-10-22 2 views
0

다음 필드에 여러 필드가있는 텍스트 파일이 있습니다. 이름 : 전화 번호 : 주소 : 생년월일 : Salary 생년월일은 mm/dd/yy 형식입니다. 특정 연도의 출생 연도를 현재 연도에서 뺀 숫자를 계산하는 방법에 대해 잘 모릅니다. 나는 나이를 추출한 다음 특정 연령 그룹과 비교하여 50이라고 말할 수있다. 나는 약간의 재료를 시도했지만 이상한 숫자를 주었다. awk -F : '{print $ 4-d}' "d = $ (date)"파일 이름awk를 사용하여 텍스트 파일 파일에서 지정된 날짜의 사람의 나이를 추출하는 방법

+0

연령대 비교를 진행하는 방법에 대한 세부 정보를 포함해야합니다. 정확히 어떻게 연령 그룹을 정의합니까? 또한 샘플 데이터 및 예상 출력을 추가하는 것을 고려하십시오. – Steve

+0

60 세 미만의 사람을 기재해야합니다. – croxfade

+0

답변으로 업데이트했습니다. 질문에 답변 해 주시면 알려주세요. 건배. – Steve

답변

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"은 현재 연도 만 반환합니다. awk에는 필드를 분할 할 수있는 split 함수가 있습니다. 이 경우 날짜가 포함 된 네 번째 필드는 월/일/년을 구분하는 /입니다. split은 일을 배열로 나눕니다. 이 경우 배열 이름은 dob (생년월일)입니다. 세 번째 필드 (1 색인)에는 출생 연도가 들어 있습니다. 조건의 일부 빠른 수학은 사람의 나이가 60+인지 확인합니다. 첫 번째 입력란에 이름을 인쇄하면됩니다.

편집 2 :

귀하의 질문에 조금 더 생각 후에는 위의 방법이 실제로 완벽하게 일을 계산하지 않는 것이 분명합니다. 그것은 거친 빠른 직업이었다 (나는 유감스럽게 생각한다. ..). 그래서 여기 훨씬 더 정확할 업데이트 된 버전이 있습니다.실행 같은 : script.awk

awk -f script.awk file.txt 

내용 :

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

ty steve 이것은 나를 위해 일했으나 1949 년이나 1963 년과 같은 출생의 해를주는 것처럼 year-dob [3] 대신에 dob [3]를 사용했습니다. 또한 쉘 스크립팅을 처음 접했을 때 커맨드에있는 것들을 설명 할 수 있다면 정말 도움이 될 것입니다. (이것은 내 이해를위한 것일 뿐이므로 미래에 이런 것들을 처리 할 수 ​​있습니다.) 예를 들어 -v for와 what (date + "% Y")은 무엇이며 분할 기능은 무엇을위한 것입니다. 그리고 다시 한 번 매우 고맙습니다. – croxfade

+0

문제 없습니다. 몇 분 안에 내 대답을 업데이트하겠습니다. – Steve

+0

@AvishKansakar : 답변을 업데이트했습니다. 두 번째 방법에 대한 설명을 원하십니까? 그렇다면 나중에이 작업을해야 할 것입니다. HTH. – Steve

1

GNU의 AWK와 (작동해야하지만 당신이 어떤 샘플 입력 및 예상 출력)을 제공하지 않았기 때문에 검증되지 않은 :

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 
    } 
} 
: 대안으로

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의 원본과 마찬가지로 위의 첫 번째 솔루션에서했던 것처럼 입력 연도에 누락 된 세기를 제공하기 위해 위의 두 번째 솔루션을 수정해야합니다.

관련 문제