AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 547338
Accepted
Raymond83
Raymond83
Asked: 2019-10-18 10:43:58 +0800 CST2019-10-18 10:43:58 +0800 CST 2019-10-18 10:43:58 +0800 CST

Como poderia ser gerada uma sequência de datas aleatórias, dado o intervalo de anos?

  • 772

O que é necessário aqui é um comando que gere seis datas em um intervalo de anos (1987 a 2017). Por exemplo:

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

Como isso poderia ser feito, com sed, gawk, etc?

awk
  • 5 5 respostas
  • 4156 Views

5 respostas

  • Voted
  1. Freddy
    2019-10-18T11:48:45+08:002019-10-18T11:48:45+08:00

    Com date, shufe xargs:

    Converta as datas de início e término em "segundos desde 1970-01-01 00:00:00 UTC" e use shufpara imprimir seis valores aleatórios nesse intervalo. Encaminhe esse resultado xargse converta os valores para o formato de data desejado.

    Editar: Se você quiser que as datas do ano de 2017 sejam incluídas na saída, adicione um ano -1s ( 2017-12-31 23:59:59) à data de término. shuf -igera números aleatórios, incluindo início e fim.

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

    Saída de exemplo:

    07/12/1988
    22/04/2012
    24/09/2012
    27/08/2000
    19/01/2008
    21/10/1994
    
    • 21
  2. Best Answer
    A.B
    2019-10-18T11:31:31+08:002019-10-18T11:31:31+08:00

    Você pode transformar o problema em gerar um número aleatório entre um número que representa a primeira data possível e um número que representa a última data possível (na verdade, aquela logo após a última possível), no formato unix epoch. Todo o resto é tratado por conversões de data padrão. gawktem uma resolução de número aleatório melhor do que bash(float vs 15 bits integer), então usarei gawk. Observe que o rand()resultado N é um float tal que 0 <= N < 1, por isso o limite superior é aumentado abaixo, é um limite que não pode ser rolado. Há um terceiro parâmetro opcional para o número de resultados.

    #!/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)
        }
    }   
    

    Por exemplo:

    ./randomdate.gawk 1987 2017 6
    26/04/1992
    28/04/2010
    21/04/2005
    17/02/2010
    06/10/2016
    04/04/1998
    
    • 10
  3. glenn jackman
    2019-10-18T13:15:57+08:002019-10-18T13:15:57+08:00

    Perl:

    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
    

    Saída de amostra:

    10-01-1989
    30-04-1995
    10-12-1998
    02-01-2016
    04-06-2006
    11-04-1987
    
    • 10
  4. Jeff Schaller
    2019-10-18T11:29:33+08:002019-10-18T11:29:33+08:00

    Aqui está uma maneira, principalmente em awk:

    #!/bin/sh
    
    [ "$end" -ge "$start" ] || exit 1
    
    awk -v start=$1 -v end=$2 '
      BEGIN {
        srand();
        for(i=1; i <= 6; i++)
          printf "%02d/%02d/%d\n", 1 + rand() * 28, 1 + rand() * 12, start + rand() * (end-start);
      }
    ' < /dev/null
    

    O shell script pega dois parâmetros e os passa como variáveis ​​para o awk, que não lê nenhuma entrada e faz todo o trabalho no BEGINbloco.

    Depois de semear o gerador de números aleatórios, ele faz um loop 6 vezes em uma printfinstrução. Essa instrução print seleciona um subconjunto das datas possíveis no intervalo, gerando um número aleatório entre 1 e 28 para o dia (sendo seguro para fevereiro), entre 1 e 12 para o mês e entre os anos de início e término fornecidos. É aleatório, mas não é uma cobertura completa - nunca imprimirá os dias 29-31 nos meses que os tiverem.

    Outra maneira, usando os recursos de data e bash do GNU:

    #!/bin/bash
    
    start=$1
    end=$2
    
    [[ "$start" -le "$end" ]] || exit 1
    
    startsec=$(date -d "1/1/$start" +%s)
    for((i=1; i<=6; i++))
    do
      r=$((RANDOM % (1 + end - start)*365*24*60*60))
      date -d @$((startsec + r)) +%d/%m/%Y
    done
    

    Ele funciona calculando os segundos desde o epoc de 1º de janeiro na data de início e, em seguida, para cada um dos loops, ele apresenta um número aleatório de segundos de deslocamento a serem adicionados; o número aleatório é limitado ao número de segundos que abrangem o intervalo fornecido. A data GNU então manipula essa data no formato desejado.

    • 9
  5. icarus
    2019-10-18T11:24:45+08:002019-10-18T11:24:45+08:00

    Se a diferença no número de anos for inferior a cerca de 90, você pode usar a $RANDOMvariável no bash para fornecer um deslocamento no número de dias e usar a capacidade limitada do datecomando para fazer o cálculo.

    #!/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
    

    O loop interno para selecionar o número aleatório tenta corrigir o viés. Se uma fonte de números aleatórios puder fornecer 0, 1, 2, 3, 4, 5, 6, 7, 8 ou 9 igualmente e você quiser um número aleatório entre 0 e 3 inclusive, se você obtiver 0 ou 1 da fonte você reporta 0, se tira 2 ou 3, então reporta 1, se tira 4 ou 5 reporta 2, se tira 6 ou 7 reporta 3, e se tira 8 ou 9 você ignora este número da fonte .

    • 5

relate perguntas

  • remova o número de linhas duplicadas com base na correspondência antes da primeira vírgula

  • anexar linhas após outros arquivos linha por linha

  • Como remover uma única linha entre duas linhas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve