여기에 필요한 것은 연도 범위(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년 미만인 경우 $RANDOM
bash의 변수를 사용하여 날짜 오프셋을 제공하고 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을 보고합니다. 소스.