In #! / Bin / bash. Comando Unix per ottenere la data del primo di un giorno feriale in un mese


8

Sto cercando comandi Unix per ottenere la prima domenica del mese prossimo, il primo lunedì del mese successivo, il primo martedì del mese successivo, il primo mercoledì del mese successivo ecc.

  1. Ne avrò bisogno nel formato data completo (l'ora non è obbligatoria)

  2. Posso ottenere numeri come 2, 3, 4 ecc. Dato che non voglio solo numeri, ne avrò bisogno nel formato data (include giorno, mese, anno)

    $ 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. Avrò bisogno di queste date per inviare notifiche per il gruppo e-mail.

Es: potrei ottenere il primo sabato del prossimo mese come di seguito.

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

$ firstsaturday=$(date -d "$firstofmonth" '+%Y-%m')-$((7 - \
                $(date -d "$firstofmonth" '+%u')     ))    
2017-04-1

Risposte:


11

In ksh93:

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

bash, poiché 4.2 ora supporta a %(<format)Tnel suo printfbuitin, ma non la possibilità di analizzare questo tipo di espressione di data.

Se dovessi usarlo bashe volessi usarlo %(<format>)T, potresti comunque farlo senza biforcarti con qualcosa del tipo:

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"

#! / bin / bash. Ricevo l'errore di seguito in bash $ printf '% (% F) T \ n' 'il mese prossimo, primo lunedì' -bash: printf: `(': carattere formato non valido
Hima

1
@Hima, l'ho detto in ksh93 . bashè un clone incompiuto di ksh (con alcune caratteristiche di (t) csh e zsh e anche alcuni dei suoi). Le versioni recenti di bashhanno aggiunto il supporto per printf '%(format)T'from ksh93, ma non la possibilità di analizzare questo tipo di specifiche della data. Sostituisci il tuo she-bang con #! /path/to/ksh93 -.
Stéphane Chazelas,

" bashè un clone incompiuto di ksh" - Mi sono sempre sentito così.
Tim Kennedy,

@Stephene, ho provato con il comando seguente per ottenere il mese prossimo sabato $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 28 Visualizza il numero 28, ma sto cercando la data completa 28/04/2017, per favore suggeriscilo se possibile.
Hima,

9

Supponendo GNU date(per quello -dche stai usando te stesso) e una zshshell simile 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

Sostituisci awk Moncon qualunque giorno della settimana sia necessario (usa LC_ALL=Cper ottenere i nomi dei mesi in inglese indipendentemente dalle impostazioni locali dell'utente). Inoltre, potrebbe essere meglio archiviarlo in una variabile se eseguirai una nuova query per ogni giorno della settimana:

$ 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

Anche in bash, questo codice restituisce il mese successivo primo dom, lun, mer, quindi, ven, sab. Grazie. Penso che posso modificare questo comando per ottenere il prossimo mese scorso domenica, lun, mer ecc. Fammi provare.
Hima,

Ciao, ho provato il comando seguente per ottenere il mese prossimo sabato $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 Visualizza il numero 28, ma sto cercando la data completa come 28/04/2017, per favore suggeriscilo se possibile.
Hima

"per i tra {1..7}; data '+% Y-% m-% d% a' -d" $ (data +% Y% m01 -d '2 mesi') $ {i} giorni fa "; done | awk '/ Sat / {print $ 1}'" - questo darà il 29-04-2017, che è l'ultimo sabato del mese successivo. Questo codice va avanti di 2 mesi, fino al primo giorno di quel mese, quindi torna indietro di 1-7 giorni per ottenere i dati degli ultimi 7 giorni del mese precedente. Personalmente eviterei di usare cal poiché ho provato gli altri esempi qui e nessuno funziona affatto sulla mia versione (CentOS 6).
Parkamark

2

PHP in realtà rende abbastanza facile analizzare le date con input testuali, se è disponibile sul tuo sistema.

Esempio:

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

Ho questa funzione nel mio .bashrc:

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

Che posso usare come:

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

Modifica Aggiunta dell'opzione da utilizzarecal

Quasi ogni sistema che bashavrà avrà cal. Il programma del calendario. È possibile ottenere un elenco della data per il primo di ogni giorno della settimana eseguendo una combinazione di cal, datee awk, come 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; }'

Che ti darà il seguente output:

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

Passare $2a $NFnell'istruzione awk per ottenere la data dell'ultima occorrenza di ogni giorno in un mese.


Non funziona in bash, $ php -qr 'date_default_timezone_set ("UTC"); echo date ("dmY \ n", strtotime ("primo lunedì del prossimo mese")); ' -bash: php: comando non trovato. per favore fatemi sapere come farlo anche in bash. e anche, il comando per ottenere il mese prossimo da domenica a sabato. L'ho provato, in alcuni casi come genera errori. Grazie ..!!
Hima,

Significa che non hai phpinstallato. Ho aggiornato con un esempio che utilizza le cal, datee awkcomandi.
Tim Kennedy,

Ho provato questo comando e genera un errore. Grazie.!! $ cal -hN $ (data -d 'mese prossimo' +% b ''% Y) | grep -v $ (data -d 'prossimo mese' +% b) | awk -v date = $ (date -d 'prossimo mese' +% Y-% m-) '{printf "% s:" date "% 02i \ n", $ 1, $ 2; } 'cal: opzione non valida - h utilizzo: cal [-13smjyV] [[mese] anno]
Hima
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.