Bash: decrementando a data americana em 1 dia mmddyyyy

0

Para simplificar o problema, digamos que eu tenha variável: dat="10152015" (representando 15 de outubro de 2015) o resultado para dat deve ser 10142015

Note que não estou usando a data de hoje.

O que tenho problema é pensar em uma maneira de diminuir a data em 1 dia. Eu poderia simplesmente diminuir o 4º dígito, mas este é um calendário.

Meu pensamento atual é converter isso em um formato que o unix entende (o que quer que seja), então tente trabalhar a partir daí, e então converta a resposta de volta

    
por CaptainObv 22.11.2015 / 01:22

5 respostas

2

requer data do GNU:

dat="10152015"
date -d "${dat:4}${dat:0:4} yesterday" +%m%d%Y 

YYYYMMDD é um formato de data ISO 9601 e o formato empacotado MMDDYYYY pode ser traduzido para isso simplesmente trocando as duas metades usando uma expansão de substring comum.

isso requer gnu date, não acho que outras versões de data suportem a exibição de horário não atual.

    
por 22.11.2015 / 08:33
1

Isso primeiro usa sed para converter o formato que você forneceu, 10152015, para o formato mm/dd/yyyy , que a implementação GNU do comando date , com suas opções -d entendem. Isso é feito fazendo-se eco da data original em sed , que insere as barras / . Este valor de data reformatado é armazenado em D . Em seguida, chamamos date com instruções para imprimir o formato de saída "mmddyyyy" e informamos para imprimir a data de yesterday usando $D como a data atual.

#!/bin/sh
D=$(echo "${1-10152015}" | sed 's,^\(..\)\(..\)\(....\)$,//,')
date +%m%d%Y -d"$D yesterday"
    
por 22.11.2015 / 01:45
1

bash não é o melhor shell para cálculo de data, pois seus recursos de manipulação de data são muito limitados.

com zsh :

zmodload zsh/datetime
d=03012012
strftime -rs d %m%d%Y%H ${d}12
strftime %m%d%Y $((d-86400))

com ksh93 :

d=03012012
printf "%(%m%d%Y)T\n" "${d:4}${d:0:4} yesterday"

Com bash , você teria que fazer o cálculo manualmente ou depender de perl ou algumas extensões GNU ou FreeBSD do utilitário date .

    
por 22.11.2015 / 22:03
0

@ A resposta elegante de Jasen me inspirou a pensar nessa variação, exigindo também o GNU date :

#!/bin/sh

D=${1-10152015}

YYYY=${D#????}
MMDD=${D%????}

date -d"$YYYY$MMDD yesterday" +%m%d%Y

Isso usa o processamento de substring Parameter Expansion compatível com POSIX com notação de correspondência de padrões, portanto, também é executado em qualquer POSIX /bin/sh e bash .

Isso também pode ser feito sem as variáveis intermediárias YYYY e MMDD , mas acho que elas ajudam a documentar com clareza os formatos de entrada e saída. Eles dão ao observador uma pista simbólica extra sobre o que está sendo feito, sem a adição de lógica extra. Especialmente útil porque acho que essa notação é um pouco mais enigmática do que a versão bash .

    
por 22.11.2015 / 21:35
-1

Nota: o seguinte assume a data do GNU a partir do GNU coreutils. Adapte-se à data do seu sistema se você tiver um utilitário date diferente.

Seu pensamento está correto, você precisa converter em segundos desde a época (1 de janeiro de 1970, 00:00:00).

A data do GNU é razoavelmente flexível nos formatos de data que irá interpretar, mas o MMDDAAA não é um deles. Felizmente, você pode usar sed para reformatar a data (no formato AAAA-MM-DD) antes de fornecê-la a date -d

dat="10152015"
secs=$(date +%s -d $(echo "$dat" | sed -e 's/\(..\)\(..\)\(....\)/--/'))
newsecs=$((secs - 86400))
date -d "@$newsecs"
    
por 22.11.2015 / 01:47

Tags