Comment puis-je changer l'horodatage du nom de fichier?

8

J'ai les noms des fichiers dat dans l'ordre chronologique:

FileName_YYYY_MM_DD_HHMM.dat

Existe-t-il des commandes pour ajouter 30 minutes à chaque horodatage?

fraise
la source
1
ces horodatages sont-ils identiques à leur date de création? est-ce la même chose que ls --full-time?
Sergiy Kolodyazhnyy
1
Non, les horodatages sont différents selon leur date de création / modification. Les horodatages sont basés sur l'heure à laquelle les données ont été mesurées.
strawberrie
1
Voyez, puisque ces horodatages sont personnalisés, cela va nécessiter un script, qui doit calculer l'ajout de 30 minutes à la date, il n'y aura pas de commande simple. il pourrait donc falloir un peu de temps pour que les gens répondent
Sergiy Kolodyazhnyy
1
y a-t-il des horodatages proches de minuit, de sorte que l'ajout de 30 minutes peut entraîner la nécessité de changer un jour par un?
Sergiy Kolodyazhnyy
1
quel format sont les heures? 12 puis 1,2,3 (format 12 heures) ou 12 à 13 à 14, 15. . . 23, 00 (format 24 heures)?
Sergiy Kolodyazhnyy

Réponses:

6

En utilisant python:

#!/usr/bin/env python2
import glob, re, os, datetime
os.chdir('/path/to/dir')
for f in glob.glob('*.dat'):
    ini_time = datetime.datetime.strptime(re.search(r'(?<=_)(?:\d|_)+(?=.dat$)', f).group(), '%Y_%m_%d_%H%M')
    fin_time = (ini_time + datetime.timedelta(minutes=30)).strftime('%Y_%m_%d_%H%M%S')
    os.rename(f, 'Filename_' + str(fin_time) + '.dat')
  • os.chdir('/path/to/dir')changera le répertoire courant en répertoire contenant les .datfichiers. Remplacez /path/to/dirpar le chemin réel.

  • glob.glob('*.dat') trouvera les fichiers se terminant par .dat

  • ini_timeLa variable supprimera d'abord la date-heure du nom de fichier d'origine à l'aide du remodule, puis triera quelle entrée représente quoi dans la chaîne qui est supprimée afin que nous puissions ajouter le temps requis à cette

  • fin_timecontiendra le temps résultant, c'est-à-dire ini_timeplus 30 minutes

  • os.rename renommera le fichier en conséquence.

Notez également que, avec des noms de fichiers successifs (différés de 30 minutes), le fichier renommé remplacera le suivant, il est donc préférable d'ajouter les secondes au nom de fichier renommé afin qu'il reste sécurisé. Sinon, vous devez enregistrer les fichiers renommés dans un répertoire différent, puis les remplacer par les fichiers d'origine ultérieurement.

heemayl
la source
Toi et python, un grand amour. =) +1
AB
Vous ne devez pas utiliser la chaîne Filename_dans la méthode de renommage.
AB
@AB Pourquoi ça? (+1 pour vous aussi)
heemayl
Savez-vous pourquoi certains fichiers manquent après l'exécution du script python? L'horodatage de chaque fichier a une différence de 30 minutes. Voici la sortie des premiers noms de fichiers: Filename_2011_01_11_1630.dat Filename_2011_01_11_1830.dat Filename_2011_01_11_1900.dat Filename_2011_01_11_2030.dat Filename_2011_01_11_2100.dat
fraise
@strawberrie Je ne sais pas..il l'a testé et fonctionne bien pour moi sans aucun problème..avez-vous exécuté le script /path/to/file par le chemin complet du répertoire?
heemayl
2

À l'aide de bash, les fichiers renommés se trouvent dans un nouveau sous-dossier renamed.

Démarrez le script dans le dossier où se trouvent les fichiers.

#!/bin/bash

mkdir -p renamed   

# loop over all dat files in the current folder
for f in *.dat; do

    # the filename without extension    
    filename="${f%%.*}"

    # your timestamp
    old_timestamp=$(echo $filename | grep -P "[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{4}$")

    if [ "$old_timestamp" == "" ]; then
        >&2 echo "not a valid filename: '$f', skipped."
    else
      # a valid date from the timestamp
      new_date=$(echo "$old_timestamp" | awk -F_ '{HM=NF; D=NF-1; M=NF-2; Y=NF-3; print $Y "-" $M "-" $D " " substr($HM,1,2) ":" substr($HM,3,2) ":00"}')

      # the new time stamp, 30 mins in the future
      changed_timestamp=$(date --date "$new_date 30 minutes" "+%Y_%m_%d_%H%M")

      # copy the file, ${f##*.} is the extension
      cp "$f" renamed/"${filename/$old_timestamp/$changed_timestamp.${f##*.}}"
    fi
done

exemple de sortie:

% ls -og FileName*
-rw-rw-r-- 1 0 Mai 16 20:35 FileName_2015_05_16_2235.dat

% ./timestamp

% ls -og renamed/FileName*
-rw-rw-r-- 1 0 Mai 16 20:35 FileName_2015_05_16_2305.dat
UN B
la source
@strawberrie les fichiers renommés sont maintenant placés dans un sous-dossierrenamed
AB
bonne idée d'enregistrer des fichiers renommés dans un dossier supplémentaire. En cas de problème, OP contient toujours des originaux. Bonne pensée, donc +1
Sergiy Kolodyazhnyy
Merci @AB J'ai eu l'erreur suivante après avoir exécuté votre script: TimeChange.sh: 21: TimeChange.sh: Substitution incorrecte Mon nom de fichier réel ou le préfixe fixe avant l'horodatage est comme FileName_123.Data_YYYY_MM_DD_HHMM.dat
fraberrie
Par définition, pour FileName_123.Data_YYYY_MM_DD_HHMM.datla partie .Data_YYYY_MM_DD_HHMM.datest l'extension. Et FileName_123n'est donc pas un horodatage valide.
AB
@strawberrie J'ai changé mon script
AB
1

SCÉNARIO

Ceci est la version éditée de mon script original. OP ne fournissait pas à l'origine d'informations complètes sur le format de dénomination. Ce script s'adapte à ce que OP a mentionné dans les commentaires était la dénomination correcte du fichier.

* Notes techniques: *

Dans ce script, nous séparons le nom de fichier en 6 champs distincts en utilisant awk, avec un trait de soulignement comme délimiteur de champ. Les deux premiers champs, $ 1 et $ 2 sont considérés comme une chaîne de texte statique. Les champs 3,4,5 et 6 sont l'horodatage auquel les données d'OP ont été échantillonnées, pas la date de création du fichier sur le système de fichiers.

La variable COPYDIR contient le nom du nouveau répertoire où les fichiers avec l'horodatage mis à jour iront. Nous créons ce répertoire dans le répertoire de travail actuel avecmkdir $COPYDIR

Les variables TEXTSTRING et DATESTRING contiennent respectivement le texte statique et l'horodatage. Dans l'exemple ci-dessous, j'ai utilisé deux chaînes différentes pour prouver que le script fonctionnera quel que soit le texte des deux premiers champs.

NEWEPOCHTIME est une variable qui contient le nouvel horodatage calculé au format d'époque unix. NEWDATE est une variable qui contient l'horodatage converti de l'époque unix au format AAAA-MM-JJ HH: MM. NEWAPPEND est l'horodatage réel qui sera ajouté au fichier au format YYYY_MM_DD_HHMM OP souhaité.

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat copie l'ancien fichier dans le répertoire "convert_files" (au lieu de le déplacer, pour éviter la perte de données) avec le datastamp mis à jour.

Remarquez , le script fonctionnera tant que le format de nommage est vraiment suivi, c'est-à-dire que tous les fichiers ont vraiment un SomeText_123.Data_YYYY_MM_DD_HHMM.datformat.

#!/usr/bin/env bash
#
# Author: Serg Kolo
# Description: this script takes timestamp within the filename
# (which may be different from file's actual creation date)
# converts that date and time to unix's epoch time
# adds 30 minutes to it and renames it

COPYDIR="converted_files"
mkdir $COPYDIR

for file in *.dat; do
        TEXTSTRING=$(stat -c %n $file | awk -F'_' '{print $1"_"$2"_"}' )
        DATESTRING=$( stat -c %n $file | awk -F'_' '{gsub(".dat","");  print $3"-"$4"-"$5" "$6}' )
        NEWEPOCHTIME=$( expr $( date --date="$DATESTRING" +%s ) + 1800 )
        NEWDATE=$(date --date=@"$NEWEPOCHTIME" +%F"_"%R)
        NEWAPPEND=$(echo $NEWDATE | awk '{gsub("-","_");gsub(":","");print}')
        cp $file "$COPYDIR"/"$TEXTSTRING""$NEWAPPEND".dat
done

SCRIPT EN ACTION

La démonstration ci-dessous est une copie directe de mon terminal. Notez que j'ai créé des fichiers originaux avec deux chaînes différentes dans les deux premiers champs. Donc, ce script devrait fonctionner, peu importe ce qui se trouve au début du nom de fichier, tant qu'il n'y a vraiment que deux chaînes séparées par un trait de soulignement

Le script a été nommé notes-conversionparce que j'ai développé le script à partir des notes que j'ai prises en travaillant sur cette question.

Notez que les noms de fichiers dont la partie HHMM est 2345 (soit 15 minutes avant minuit) sont mis à jour à 0015 et la partie DD est mise à jour le jour suivant. Format 24 heures conservé.

De plus, comme la boucle ne recherche que des .datfichiers, nous évitons de renommer d'autres fichiers ou répertoires qui peuvent se trouver dans le répertoire de travail, évitant ainsi toute perte de données potentielle. Dans l'exemple ci-dessous, le répertoire d'origine contient 11 éléments, dont 3 sont des *.txtfichiers à tester, nous ne travaillons donc qu'avec 8 .datfichiers. Dans le répertoire où vont les fichiers mis à jour, nous voyons 8 fichiers, tous .datet aucun autre fichier. Les données sont en sécurité, le script fait son travail.

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
85 $ ls
FileName_123.Dat_2015_05_31_1245.dat  Test.txt
FileName_123.Dat_2015_05_31_2345.dat  YoloSwag_123.Dat_2015_05_31_1245.dat
FileName_Foo.Bar_2015_05_31_1245.dat  YoloSwag_123.Dat_2015_05_31_2345.dat
FileName_Foo.Bar_2015_05_31_2345.dat  YoloSwag_Foo.Bar_2015_05_31_1245.dat
File.txt                              YoloSwag_Foo.Bar_2015_05_31_2345.dat
Random.txt

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
86 $ ls | wc -l
11

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
87 $ notes-conversion                                                                                

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
88 $ ls converted_files/; ls converted_files/ | wc -l                                                
FileName_123.Dat_2015_05_31_1315.dat  YoloSwag_123.Dat_2015_05_31_1315.dat
FileName_123.Dat_2015_06_01_0015.dat  YoloSwag_123.Dat_2015_06_01_0015.dat
FileName_Foo.Bar_2015_05_31_1315.dat  YoloSwag_Foo.Bar_2015_05_31_1315.dat
FileName_Foo.Bar_2015_06_01_0015.dat  YoloSwag_Foo.Bar_2015_06_01_0015.dat
8

[67 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
89 $ 

EXPLICATION (du message d'origine)

*) Aujourd'hui, j'ai appris que les systèmes Unix-Linux comptent le temps dans le temps Epoch , ou simplement mettent des secondes.

*) le script prend chaque nom de fichier, extrait la date, le convertit en époque, ajoute 1800 secondes (soit exactement 30 minutes) et enregistre le fichier avec ce nouvel horodatage.

*) Ce script répond à ce que voulait OP - changer l'horodatage du nom de fichier, pas mettre à jour l'heure de création du fichier lui-même

Les outils utilisés:

  • ubuntu 15.04

  • GNU bash 4.3.30

  • GNU awk 4.1.1

  • date (GNU coreutils) 8.23

Sergiy Kolodyazhnyy
la source
au fait, ls | wc -l donne avant 36 fichiers, et après script également 36 fichiers, aucun manquant
Sergiy Kolodyazhnyy
Aussi, la raison pour laquelle j'utilise le fichier stat -c% n, est que l'analyse de la sortie de ls n'est généralement pas une bonne idée. Certaines personnes utilisent la findcommande, ce qui est également bon.
Sergiy Kolodyazhnyy
Merci @Serg. Je ne sais pas pourquoi je n'ai laissé que 2 des 727 fichiers dans le dossier après avoir exécuté votre script ...
Strawberrie
Y avait-il une différence entre les noms de fichiers réels et l'exemple que vous avez publié?
Sergiy Kolodyazhnyy
aussi, avez-vous exécuté la première ligne du "Script en action"? le rm * était pour nettoyer mon propre répertoire, puis créer un tas de fichiers de test avec différentes dates dans les noms de fichiers. Vous n'étiez pas censé diriger cela
Sergiy Kolodyazhnyy
-1

Vous pouvez utiliser ce code pour faire ce dont vous avez besoin en supposant

  1. vous devez prendre une sauvegarde et tester d'abord le code pour voir s'il convient à votre cas
  2. vous utilisez le format 24H
  3. aucun fichier ne sera nommé après 23h29 (si vous avez des fichiers après cette heure, le code doit être modifié pour changer également la date)

le code est:

cd /path/to/the/files

for i in `ls`; do MM=${i:(-6): -4}; HH=${i: -8 : -6 }; NAME=${i: 0 : -8 } ; if [ "$MM" -lt 30 ] ; then  NEWMM=$((10#$MM+30)); mv -f $i $NAME$HH$NEWMM.dat ; else NEWHH=$((10#$HH+1));NEWMM=$((10#$MM-30)) ; mv -f $i $NAME$NEWHH$NEWMM.dat ; fi ; done ;

Comment ça marche: Le code vérifiera la partie minutes dans le nom du fichier MMpuis s'il est inférieur à 30 il ajoutera 30 à MMs'il est égal à 30 ou plus il ajoutera 1 heure à la HHpartie dans le nom et déduira 30 minutes de la MMune partie du nom

Fat Mind
la source
pour l'électeur, veuillez en informer la raison?
Fat Mind