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

8

Estou procurando por comandos Unix diretos para obter o primeiro domingo do próximo mês, a primeira segunda-feira do próximo mês, a primeira terça-feira do próximo mês, a primeira quarta-feira do próximo mês etc.

  1. Vou precisar deles no formato completo da data (a hora não é obrigatória)

  2. Posso obter números como 2, 3, 4 etc. Como não quero apenas números, precisarei 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 email.

Ex: eu poderia receber 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
Hima
fonte

Respostas:

11

Em ksh93:

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

bash, Desde 4.2 agora suporta um %(<format)Tem sua printfbuitin, mas não a capacidade de analisar este tipo de expressão de data.

Se você tivesse que usar bashe quisesse usá-lo %(<format>)T, ainda poderia fazê-lo sem usar 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"
Stéphane Chazelas
fonte
#! / bin / bash. Estou recebendo o erro abaixo no bash $ printf '% (% F) T \ n' 'no próximo mês, primeira segunda-feira' -bash: printf: `(': caractere de formato inválido
Hima 6/17
1
@ Hima, eu disse em ksh93 . bashé um clone inacabado do ksh (com alguns recursos de (t) csh e zsh e até alguns deles). Versões recentes de bashadicionaram suporte para printf '%(format)T'from ksh93, mas não a capacidade de analisar esse tipo de especificações de data. Substitua seu she-bang por #! /path/to/ksh93 -.
Stéphane Chazelas
" bashé um clone inacabado do ksh" - sempre me senti assim.
Tim Kennedy
@Stephene, tentei com o comando abaixo para obter o próximo mês no último sábado $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 28 Ele exibe o número 28, mas estou procurando a data completa 28/04/2017, plz sugere se possível com ele.
Hima
9

Supondo que o GNU date(para isso -dvocê está usando a si mesmo) e um zshshell semelhante a {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 awk Monpor qualquer dia da semana necessário (use LC_ALL=Cpara obter os nomes dos 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 fazer uma nova consulta 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
parkamark
fonte
No bash também, esse código retorna no próximo mês primeiro Dom, Seg, Qua, Assim, Sex, Sáb. Obrigado. Penso que posso modificar este comando para obter no próximo mês último domingo, seg, qua etc. Deixe-me tentar isso.
Hima
Olá, tentei o comando abaixo para obter o próximo mês no último sábado $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 Ele exibe o número 28, mas estou procurando a data completa como 28/04/2017, plz sugere se possível.
Hima
"para i em {1..7}; data '+% Y-% m-% d% a' -d" $ (data +% Y% m01 -d '2 meses') $ {i} dias atrás "; done | awk '/ Sat / {print $ 1}'" - isso dará 29-04-2017, que é o último sábado do próximo mês. Esse código avança 2 meses, até o primeiro dia desse mês e, em seguida, retorna de 1 a 7 dias para obter os dados dos últimos 7 dias do mês anterior. Pessoalmente, eu evitaria o uso de cal, já que tentei os outros exemplos aqui e nenhum funciona na minha versão (CentOS 6).
parkamark
2

Na verdade, o PHP facilita a análise de datas com entrada de texto, se disponível 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\"));"
}

Que eu posso usar como:

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

Editar opção Adicionando para usarcal

Quase todo sistema que possui bashterá cal. O programa de calendário. Você pode obter uma lista de data para o primeiro de cada dia da semana, executando uma combinação de cal, datee awk, como segue:

 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 fornecerá 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 $2para $NFna declaração awk para obter a data da última ocorrência de cada dia em um mês.

Tim Kennedy
fonte
Não está funcionando no bash, $ php -qr 'date_default_timezone_set ("UTC"); data do eco ("dmY \ n", strtotime ("primeira segunda-feira do próximo mês")); ' -bash: php: comando não encontrado. informe-me também como fazê-lo no bash. e também, o comando para chegar no próximo mês no último domingo até o sábado. Eu tentei, de alguma forma, como lança erros. obrigado ..!!
Hima
Os meios que você não phpinstalou. Tenho atualizado com um exemplo que usa as cal, datee awkcomandos.
Tim Kennedy
Eu tentei este comando e lança um erro. Obrigado.!! $ cal -hN $ (data -d 'próximo mês' +% b ''% Y) | grep -v $ (data -d 'próximo mês' +% b) | awk -v data = $ (data -d 'próximo mês' +% Y-% m-) '{printf "% s:" data "% 02i \ n", $ 1, $ 2; } 'cal: opção inválida - h uso: cal [-13smjyV] [[mês] ano]
Hima