Dans #! / Bin / bash. Commande Unix pour obtenir la date du premier jour de la semaine d'un mois

8

Je cherche des commandes Unix droites pour obtenir le premier dimanche du mois prochain, le premier lundi du mois prochain, le premier mardi du mois prochain, le premier mercredi du mois prochain, etc.

  1. J'en aurai besoin dans le format de date complet (l'heure n'est pas obligatoire)

  2. Je peux obtenir des nombres comme 2, 3, 4 etc. Comme je ne veux pas que des nombres, j'en aurai besoin au format date (comprend le jour, le mois, l'année)

    $ 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. J'aurai besoin de ces dates pour envoyer des notifications au groupe de messagerie.

Ex: je pourrais avoir le premier samedi du mois prochain comme ci-dessous.

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

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

Réponses:

11

Dans ksh93:

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

bash, puisque 4.2 prend désormais en charge a %(<format)Tdans sa printfbuitine, mais pas la possibilité d'analyser ce type d'expression de date.

Si vous deviez l'utiliser bashet que vous vouliez l'utiliser %(<format>)T, vous pourriez toujours le faire sans bifurquer avec quelque chose comme:

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
la source
#! / bin / bash. J'obtiens l'erreur ci-dessous dans bash $ printf '% (% F) T \ n' 'le mois prochain, le premier lundi' -bash: printf: `(': caractère de format invalide
Hima
1
@Hima, je l'ai dit dans ksh93 . bashest un clone inachevé de ksh (avec certaines fonctionnalités de (t) csh et zsh et même quelques-unes des siennes). Les versions récentes de bashont ajouté la prise en charge printf '%(format)T'de ksh93, mais pas la possibilité d'analyser ce type de spécifications de date. Remplacez votre she-bang par #! /path/to/ksh93 -.
Stéphane Chazelas
" bashest un clone inachevé de ksh" - j'ai toujours ressenti cela.
Tim Kennedy
@Stephene, j'ai essayé avec la commande ci-dessous pour obtenir le mois prochain samedi dernier $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | queue -1 28 Il affiche le nombre 28, mais je recherche la date complète 28/04/2017, plz suggérer si possible avec elle.
Hima
9

En supposant GNU date(pour cela que -dvous utilisez vous-même), et un zshshell semblable à {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

Remplacez le awk Monpar le jour de la semaine requis (utilisez LC_ALL=Cpour obtenir les noms des mois en anglais, indépendamment des paramètres régionaux de l'utilisateur). En outre, il peut être préférable de stocker cela dans une variable si vous effectuez une nouvelle requête pour chaque jour de la semaine:

$ 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
la source
En bash également, ce code renvoie le mois suivant les premiers dim, lun, mer, donc, ven, sam. Je vous remercie. Je pense que je peux modifier cette commande pour obtenir le mois prochain dimanche, lundi, mercredi, etc. Laissez-moi essayer.
Hima
Salut, j'ai essayé la commande ci-dessous pour obtenir le mois prochain samedi dernier $ cal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | queue -1 Il affiche le nombre 28, mais je recherche la date complète comme 28/04/2017, plz suggère si c'est possible.
Hima
"for i in {1..7}; do date '+% Y-% m-% d% a' -d" $ (date +% Y% m01 -d '2 months') il y a $ {i} jours "; done | awk '/ Sat / {print $ 1}'" - cela donnera le 2017-04-29, qui est le dernier samedi du mois suivant. Ce code avance de 2 mois au premier jour de ce mois, puis revient de 1 à 7 jours pour obtenir les données des 7 derniers jours du mois précédent. J'éviterais personnellement d'utiliser cal car j'ai essayé les autres exemples ici et aucun ne fonctionne du tout sur ma version (CentOS 6).
parkamark
2

PHP facilite en fait l'analyse des dates avec une entrée textuelle, si elle est disponible sur votre système.

Exemple:

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

J'ai cette fonction dans mon .bashrc:

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

Que je peux utiliser comme:

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

Modifier l' option d'ajout à utilisercal

Presque tous les systèmes qui l'ont bashauront cal. Le programme du calendrier. Vous pouvez obtenir une liste de la date en exécutant une combinaison de la première de chaque jour de la semaine cal, dateet awk, comme suit:

 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; }'

Ce qui vous donnera la sortie suivante:

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

Passez $2à $NFdans l'instruction awk pour obtenir la date de la dernière occurrence de chaque jour d'un mois.

Tim Kennedy
la source
Cela ne fonctionne pas en bash, $ php -qr 'date_default_timezone_set ("UTC"); echo date ("dmY \ n", strtotime ("premier lundi du mois prochain")); ' -bash: php: commande introuvable. s'il vous plaît laissez-moi savoir la façon de le faire aussi en bash. et aussi, la commande pour obtenir le mois prochain le dimanche dernier à samedi. Je l'ai essayé, certains comment il génère des erreurs. Merci ..!!
Hima
Le moyen que vous n'avez pas phpinstallé. Je l' ai mis à jour avec un exemple qui utilise les cal, dateet les awkcommandes.
Tim Kennedy
J'ai essayé cette commande et jette une erreur. Je vous remercie.!! $ cal -hN $ (date -d 'mois prochain' +% b ''% Y) | grep -v $ (date -d 'mois prochain' +% b) | awk -v date = $ (date -d 'mois prochain' +% Y-% m-) '{printf "% s:" date "% 02i \ n", $ 1, $ 2; } 'cal: option non valide - h utilisation: cal [-13smjyV] [[mois] année]
Hima