Em #! / bin / bash. Comando Unix para obter a data do primeiro dia da semana em um mês

8

Eu estou procurando por um comando direto do Unix para obter o primeiro domingo do próximo mês, primeira segunda-feira do próximo mês, primeira terça-feira do próximo mês, primeira quarta-feira do próximo mês etc.

  1. Vou precisar deles no formato de data completo (o tempo não é obrigatório)

  2. Eu posso conseguir números como 2, 3, 4 etc. Como eu não quero apenas números, eu preciso deles em formato de data (inclui dia, mês, ano)

    $ NEXT_MONTH='date +'%m %Y' -d 'next month''
    $ echo $NEXT_MONTH
    04 2017
    
    $ NEXT_SUNDAY='cal $NEXT_MONTH | awk 'NF==7 && !/^Su/{print $1;exit}''
    $ echo $NEXT_SUNDAY
    2
    
  3. Vou precisar dessas datas para enviar notificações para o grupo de e-mail.

Ex: Eu poderia ter o primeiro sábado do próximo mês como abaixo.

$ firstofmonth=$(date -d '+1 months' '+%Y%m01')
20170401

$ firstsaturday=$(date -d "$firstofmonth" '+%Y-%m')-$((7 - \
                $(date -d "$firstofmonth" '+%u')     ))    
2017-04-1
    
por Hima 03.03.2017 / 22:05

3 respostas

11

Em ksh93 :

$ printf '%(%F)T\n' 'next month, first Monday'
2017-04-03

bash , já que o 4.2 agora suporta %(<format)T no seu printf buitin, mas não a capacidade de analisar esse tipo de expressão de data.

Se você tivesse que usar bash e queria usar esse %(<format>)T , você ainda poderia fazer isso sem bifurcar com algo como:

printf -v code '%(
  t=$((%s + (12 - %-H) * 60 * 60))
  increment=$((8 - %u))
  current_month=%m)T' -1
eval "$code"
until
  t=$((t + increment * 24 * 60 * 60)) # next Monday around mid-day
  printf -v code '%(date=%F month=%m)T' "$t"
  eval "$code"
  [ "$month" != "$current_month" ] # until be get to next month
do
  increment=7 # the first increment is the number of days
              # til Monday. Next increments are just a week.
done
echo "$date"
    
por 03.03.2017 / 22:23
9

Assumindo que o GNU date (para esse -d você está usando a si mesmo) e um% de shell semelhante aozsh para {1..7} :

$ for i in {1..7} ; do \
    LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
  done | awk '/Mon/ {print $1}'
2017-04-03

Substitua o awk Mon por qualquer dia da semana necessário (use LC_ALL=C para obter nomes de meses em inglês, independentemente da localidade do usuário). Além disso, pode ser melhor armazenar isso em uma variável se você for reenviar para cada dia da semana:

$ days=$(for i in {1..7} ; do \
           LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
         done)

$ for i in Mon Tue Wed Thu Fri Sat Sun ; do \
    echo "${days}" | awk "/${i}/"'{print $1}' ; \
  done
2017-04-03
2017-04-04
2017-04-05
2017-04-06
2017-04-07
2017-04-01
2017-04-02
    
por 03.03.2017 / 22:49
2

O PHP, na verdade, torna muito fácil analisar datas com entradas textuais, se estiverem disponíveis no seu sistema.

Exemplo:

bash-[522]$ php -qr 'date_default_timezone_set("UTC"); echo date("d-m-Y\n", strtotime("first monday of next month"));'
03-04-2017

Eu tenho essa função no meu .bashrc:

get_date ()
{
    text="$*";
    php -qr "date_default_timezone_set(\"UTC\"); echo date(\"d-m-Y\n\", strtotime(\"$text\"));"
}

Qual eu posso usar como:

bash-[523]$ get_date first monday of next month
03-04-2017

Editar Adicionando opção para usar cal

Quase todos os sistemas que possuem bash terão cal . O programa de calendário. Você pode obter uma lista da data do primeiro dia de cada semana executando uma combinação de cal , date e awk , da seguinte maneira:

 cal -hN $(date -d 'next month' +%b' '%Y) | grep -v $(date -d 'next month' +%b) | awk -v date=$(date -d 'next month' +%Y-%m-) '{ printf "%s: "date"%02i\n", $1, $2; }'

O que lhe dará a seguinte saída:

Su: 2017-04-02
Mo: 2017-04-03
Tu: 2017-04-04
We: 2017-04-05
Th: 2017-04-06
Fr: 2017-04-07
Sa: 2017-04-01

Altere $2 para $NF na instrução awk para obter a data da última ocorrência de cada dia em um mês.

    
por 06.03.2017 / 16:20

Tags