J'ai besoin de faire une sauvegarde d'un fichier, et je voudrais avoir un horodatage dans le nom pour faciliter la différenciation.
Comment injecteriez-vous la date actuelle dans une commande de copie?
[root@mongo-test3 ~]# cp foo.txt {,.backup.`date`}
cp: target `2013}' is not a directory
[root@mongo-test3 ~]# cp foo.txt {,.backup. $((date)) }
cp: target `}' is not a directory
[root@mongo-test3 ~]# cp foo.txt foo.backup.`date`
cp: target `2013' is not a directory
Cela ne fonctionne pas car la commande date
renvoie une chaîne contenant des espaces.
$ date
Wed Oct 16 19:20:51 EDT 2013
Si vous voulez vraiment des noms de fichiers comme celui-ci, vous devrez encapsuler cette chaîne entre guillemets.
$ touch "foo.backup.$(date)"
$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:22 foo.backup.Wed Oct 16 19:22:29 EDT 2013
Je pense que vous pensez probablement à une chaîne différente à ajouter. J'utilise habituellement quelque chose comme ça:
$ touch "foo.backup.$(date +%F_%R)"
$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:25 foo.backup.2013-10-16_19:25
Voir page de manuel pour la date pour plus de codes de formatage autour de la sortie pour la date et l'heure.
Si vous voulez prendre le contrôle total si vous consultez la page de manuel, vous pouvez faire des choses comme ceci:
$ date +"%Y%m%d"
20131016
$ date +"%Y-%m-%d"
2013-10-16
$ date +"%Y%m%d_%H%M%S"
20131016_193655
REMARQUE: Vous pouvez utiliser date -I
ou date --iso-8601
qui produira une sortie identique à date +"%Y-%m-%d
. Ce commutateur a également la possibilité de prendre un argument pour indiquer différents formats d'heure :
$ date -I=?
date: invalid argument ‘=?’ for ‘--iso-8601’
Valid arguments are:
- ‘hours’
- ‘minutes’
- ‘date’
- ‘seconds’
- ‘ns’
Try 'date --help' for more information.
Exemples:
$ date -Ihours
2019-10-25T01+0000
$ date -Iminutes
2019-10-25T01:21+0000
$ date -Iseconds
2019-10-25T01:21:33+0000
cp foo.txt {,.backup.`date`}
Cela s'étend à quelque chose comme cp foo.txt .backup.Thu Oct 17 01:02:03 GMT 2013
. L'espace avant les accolades commence un nouveau mot.
cp foo.txt {,.backup. $((date)) }
Les accolades sont dans des mots séparés, ils sont donc interprétés littéralement. De plus, $((…))
est la syntaxe de l'expansion arithmétique; la sortie de date
ne ressemble en rien à une expression arithmétique. La substitution de commandes utilise un seul jeu de parenthèses: $(date)
.
cp foo.txt foo.backup.`date`
Plus proche. Vous auriez pu exprimer cela avec des accolades comme cp foo.{txt,.backup.`date`}
. Le problème persiste: la sortie de date
contient des espaces, elle doit donc être placée entre guillemets. Cela fonctionnerait:
cp foo.{txt,backup."`date`"}
ou
cp foo.{txt,backup."$(date)"}
Le format de sortie par défaut de date
n'est pas bien adapté à un nom de fichier, et il peut même ne pas fonctionner si une locale utilise des caractères /
Dans le format de sortie par défaut. Utilisez un format de date Y-M-D pour que l'ordre lexicographique des noms de fichier soit l'ordre chronologique (et aussi pour éviter toute ambiguïté entre les formats de date américains et internationaux).
cp foo.{txt,backup."$(date +%Y%m%d-%H%M%S)"}
Si vous voulez vraiment utiliser la date détaillée, vous devez protéger le backtick. Avec ce format de date, il contient des espaces intégrés, un non-non dans un shell Unix, sauf si vous les mettez entre guillemets (ou si vous leur échappez d'une autre manière).
cp foo.txt "foo-`date`.txt"
Cependant, je préfère utiliser le format ISO plus court:
cp foo.txt foo-`date --iso`.txt
Utilisez une fonction, cela vous facilitera la vie. Voici ce que j'utilise:
backup () {
for file in "$@"; do
local new=${file}.$(date '+%Y%m%d')
while [[ -f $new ]]; do
new+="~";
done;
printf "copying '%s' to '%s'\n" "$file" "$new";
\cp -ip "$file" "$new";
done
}
Comme date
a par défaut des espaces dans sa sortie, votre dernière commande a échoué. Si vous aviez cité le dernier argument à l'intérieur avec "
, ça devrait marcher. Vos autres tentatives ont juste une syntaxe erronée
Voici une solution possible sans espaces:
cp foo.txt foo.backup.$(date --iso-8601=seconds)
ou
cp foo.txt foo.backup.`date --iso-8601=seconds`
Si vous ajoutez
bk() {
cp -a "$1" "${1}_$(date --iso-8601=seconds)"
}
à ton .bashrc
et reconnectez-vous/laissez votre bash le relire, il vous suffit d'appeler bk file.txt
.
Vous copiez le fichier dans un fichier de sauvegarde dont le nom est créé avec l'horodatage ajouté
cp foo.txt backup_`date +"%d-%m-%Y"`.txt
OU:
Vous pouvez afficher le contenu du fichier à l'aide de "cat" et rediriger la sortie vers le fichier de sauvegarde dont le nom est créé avec l'horodatage ajouté
cat foo.txt > backup_`date +"%d-%m-%Y"`.txt
Vous pouvez également utiliser plus d'options de contrôles FORMAT selon vos besoins, par exemple:% H,% M,% S, etc.
Quand je dois faire une sauvegarde d'un fichier, je le fais généralement de cette façon.
cp foo.txt foo.backup.$(date +%F).txt
ls -l
foo.txt foo.backup.2017-9-19.txt
En bash, vous pouvez taper:
cp /path/to/long/filename !#$_$(date +Is)
Qui s'étend à:
cp /path/to/long/filename /path/to/long/filename_$(date +Is)
Résultant en:
$ ls /path/to/long/filename*
filename filename_2017-05-10T11:50:10+0300
Le boeuf étant date -Is
. J'aime l'utiliser car il est facile à mémoriser, à taper et à autoriser des versions courtes (comme -In
si vous êtes un monstre de précision).
!
démarre un désignateur d'événement:
!# The entire command line typed so far.
Et $
est un désignateur Word:
$ The last Word. This is usually the last argument, but will expand to the zeroth Word if there is only one Word in the line.
Si vous voulez juste une sauvegarde du fichier ou du répertoire, alors pourquoi taper également la destination, utilisez simplement l'extension Shell pour ajouter la date à la fin du nom du fichier de copie.
c'est à dire
cp filename.sh{,."`date`"}
ce qui se traduit par
filename.sh.Sun 29 Sep 00:44:43 BST 2019
ou utilisez simplement
cp filename{,.20190929}
filename.sh.20190929
Ajoutez la date pour répondre à vos besoins. :)