연도 간격으로 임의의 날짜 시퀀스를 생성하는 방법은 무엇입니까?

연도 간격으로 임의의 날짜 시퀀스를 생성하는 방법은 무엇입니까?

여기에 필요한 것은 연도 범위(1987~2017)에 따라 6개의 날짜를 생성하는 명령입니다. 예를 들어:

12/10/1987
30/04/1998
22/02/2014
17/08/2017
19/07/2011
14/05/2004

sed어떻게 해야 할까요 gawk?

답변1

그리고 date, shuf그리고 xargs:

시작 날짜와 종료 날짜를 "1970-01-01 00:00:00 UTC 이후의 초"로 변환하고 이를 사용하여 shuf이 범위에서 임의의 값 6개를 인쇄합니다. 이 결과를 파이프 xargs하고 값을 원하는 날짜 형식으로 변환합니다.

편집하다:출력에 2017년 날짜를 포함하려면 2017-12-31 23:59:59종료 날짜에 연도-1( )을 추가해야 합니다. shuf -i시작과 끝을 포함하여 난수를 생성합니다.

shuf -n6 -i$(date -d '1987-01-01' '+%s')-$(date -d '2017-01-01' '+%s')\
 | xargs -I{} date -d '@{}' '+%d/%m/%Y'

출력 예:

07/12/1988
22/04/2012
24/09/2012
27/08/2000
19/01/2008
21/10/1994

답변2

Unix epoch 형식에서 가능한 첫 번째 날짜를 나타내는 숫자와 가능한 마지막 날짜(실제로는 가능한 마지막 날짜 이후의 날짜)를 나타내는 숫자 사이의 난수를 생성하는 문제를 변환할 수 있습니다. 다른 모든 것은 표준 날짜 변환으로 처리됩니다. gawk(부동 소수점 대 15비트 정수)보다 난수 분해능이 더 좋으므로 bash을 사용하겠습니다 gawk. rand()결과 N은 0 <= N < 1인 부동 소수점 숫자이므로 상한이 아래에서 증가합니다. 스크롤할 수 없는 한계입니다. 결과 수를 나타내는 선택적 세 번째 매개변수가 있습니다.

#!/usr/bin/gawk -f
BEGIN {
    first=mktime(ARGV[1] " 01 01 00 00 00")
    last=mktime(ARGV[2]+1 " 01 01 00 00 00")
    if (ARGC == 4) { num=ARGV[3] } else { num=1 }
    ARGC=1
    range=last-first
    srand(sprintf("%d%06d", systime(), PROCINFO["pid"]))
    for (i=1; i <= num; i++) {
        print strftime("%d/%m/%Y", range*rand()+first)
    }
}   

예를 들어:

./randomdate.gawk 1987 2017 6
26/04/1992
28/04/2010
21/04/2005
17/02/2010
06/10/2016
04/04/1998

답변3

진주:

perl -MTime::Piece -sE '
    my $t1 = Time::Piece->strptime("$y1-01-01 00:00:00", "%Y-%m-%d %H:%M:%S");
    my $t2 = Time::Piece->strptime("$y2-12-31 23:59:59", "%Y-%m-%d %H:%M:%S");
    do {
        my $time = $t1 + int(rand() * ($t2 - $t1));
        say $time->dmy;
    } for 1..6;
' -- -y1=1987 -y2=2017

예제 출력:

10-01-1989
30-04-1995
10-12-1998
02-01-2016
04-06-2006
11-04-1987

답변4

연도 차이가 약 90년 미만인 경우 $RANDOMbash의 변수를 사용하여 날짜 오프셋을 제공하고 date명령의 제한된 기능을 사용하여 계산을 수행할 수 있습니다.

#!/bin/bash
s=$(date +%s -d "1/1/$1")          # start in seconds since 1 Jan 1970
e=$(date +%s -d "1/1/$(($2+1))")   # start of end year +1 in seconds
days=$(((e-s)/(24*3600)))          # number of days from start to end
factor=$((32767/$days))            # RANDOM is 0 to 32767. See how many
toobig=$(($factor*$days))          # exact multiples of days.
                                   # if RANDOM is too large, draw again
for((i=0;i<${3:-1};i++))           # produce $3 random dates
do
    r=$RANDOM                      # find a random number < toobig
    while (( r >= toobig ))        # if toobig, then loop.
    do r=$RANDOM
    done
    offset=$(($r/$factor))         # get (0,days) from (0,factor*days)
    # output horrible day/month/year for N days past start date
    date -d "$offset days 1/1/$1" +%d/%m/%Y
done

난수를 선택하는 내부 루프는 편향을 수정하려고 시도합니다. 난수 소스가 0, 1, 2, 3, 4, 5, 6, 7, 8 또는 9를 균일하게 제공할 수 있고 0과 3(포함) 사이의 난수를 원하는 경우, 0 또는 소스에서 1을 보고 0을 보고하고, 2나 3을 얻으면 1을 보고하고, 4나 5를 얻으면 2를 보고하고, 6이나 7을 얻으면 3을 보고하고, 8이나 9를 얻으면 3을 보고합니다. 소스.

관련 정보