Comment formater la sortie de la date avec des espaces comme variable dans le script?

13

Je veux faire la datecommande avec un formatage sympa comme ceci:

$ date +"%Y-%m-%d %H:%M:%S"
2015-09-17 16:51:58

Mais je veux enregistrer cela dans une variable, donc je pourrais appeler à partir d'un script comme celui-ci: echo "$(nice_date) [WARNING] etc etc"

Mais ça ne marche pas

$ nice_date="date +%Y-%m-%d %H:%M:%S"
$ echo "$($nice_date)"
date: extra operand ‘%H:%M:%S
Try 'date --help' for more information.

$ nice_date="date +\"%Y-%m-%d %H:%M:%S\""
$ echo "$($nice_date)"
date: extra operand ‘%H:%M:%S"’
Try 'date --help' for more information.

$ nice_date='date +"%Y-%m-%d %H:%M:%S"'
$ echo "$($nice_date)"
date: extra operand ‘%H:%M:%S"
Try 'date --help' for more information.

Quelle est la bonne façon de procéder, de sorte que la commande date pour obtenir un argument correct?

gilbertasm
la source
En remarque, votre chaîne de format de date peut être raccourcie "%F %T"si vous utilisez GNU date.
jordanm
Le problème est l'espace. Si vous utilisez nice_date="date +%Y-%m-%d-%H:%M:%S", cela fonctionne. Je ne vois pas actuellement comment protéger cet espace du deuxième shell.
MadHatter

Réponses:

13

La raison pour laquelle votre exemple échoue est due au fonctionnement du fractionnement de mots du shell. Lorsque vous exécutez "$($nice_date)", le shell exécute la datecommande avec deux arguments "+%Y-%m-%d"et "%H:%M:%S". Cela échoue car la chaîne de formatage pour la date doit être un seul argument.

La meilleure façon de le faire est d'utiliser une fonction au lieu de stocker la commande dans une variable:

format_date() {
  # echo is not needed
  date "+%Y-%m-%d %H:%M:%S" "$1"
}
format_date
format_date "2015-09-17 16:51:58"
echo "$(format_date) [WARNING] etc etc"

Si vous vouliez vraiment stocker la commande dans une variable, vous pouvez utiliser un tableau:

nice_date=(date "+%Y-%m-%d %H:%M:%S")
# again echo not needed
"${nice_date[@]}" "2015-09-17 16:51:58"

Pour plus de détails sur les cas complexes de stockage d'une commande dans une variable, voir BashFAQ 050 .

jordanm
la source
Merci, mais je suis curieux de savoir pourquoi mon approche ne fonctionne pas, pouvez-vous développer cela?
gilbertasm
@gilbertasm réponse mise à jour
jordanm
1
Je reçois des date: extra operand ‘’erreurs avec les deux approches ci
Jeff Puckett
3

Je suis d'accord qu'une fonction est la meilleure façon de procéder. Comme alternative, stockez simplement le format en tant que variable plutôt que la commande entière:

$ nice_date='+%Y-%m-%d %H:%M:%S'
$ echo "$(date "$nice_date") [WARNING] etc etc"
Adam
la source
1
@Kusalananda: Tout à fait. Je vous remercie! Ont mis à jour la réponse
Adam
Et, euh, désolé, mais la echosubstitution de commande et sont également superflues.
Kusalananda
1
Oui, ils étaient techniquement superflus dans l'exemple de réduction que j'ai utilisé (je pourrais dire qu'ils produisent un code plus lisible, mais c'est une question de goût). Ont mis à jour pour utiliser l'exemple de l'OP, auquel cas ils sont nécessaires
Adam
Oui, cet exemple a plus de sens.
Kusalananda
1

La réponse la plus courte est

#if you want to store in a variable
now=$(date '+%F" "%T');
echo $now

#or direct output (single quote may not needed)
date '+%F" "%T'
Thanh Trung
la source
1

Un moyen simple consiste à simplement «s'échapper» de l'espace avec un \

nice_date="date +%Y-%m-%d\ %H:%M:%S"
user381580
la source
0

Veuillez essayer ci-dessous:

Vous devez ajouter le symbole "" le symbole qui se trouve sur la touche tilde du clavier. Le symbole indique au shell d'exécuter d'abord la commande, puis de l'assigner à la variable.

[root@RHEL01 ~]# My_Var=`date +"%Y-%m-%d %H:%M:%S"`
[root@RHEL01 ~]# echo $My_Var
2015-09-17 10:05:30
[root@RHEL01 ~]#
ZVIK
la source
Même problème que la réponse d'Iain.
MadHatter
0

Au lieu de:

nice_date="date +%Y-%m-%d %H:%M:%S"
echo "$($nice_date)"

Essayer:

nice_date_format="+%Y-%m-%d %H:%M:%S"
echo $(date "$nice_date_format")

De plus, vous n'avez pas besoin de la dernière substitution de commande:

date "$nice_date_format"
user1333144
la source
-1

Eu le même problème; a dû mettre une date dans une impression awk pour le traitement par splunk. j'ai utilisé

DATE1=`date +%Y-%m-%d`

DATE2=`date +%T`

ensuite

awk ' { print "['$DATE1' '$DATE2'] topic=" $1, etc
Mike Fester
la source
1
Pouvez-vous expliquer exactement comment cela répond à la question?
G-Man dit `` Réintègre Monica '' le