Wie kann ich den Dateinamen-Zeitstempel ändern?

8

Ich habe die Namen der Datendateien in chronologischer Reihenfolge:

FileName_YYYY_MM_DD_HHMM.dat

Gibt es Befehle zum Hinzufügen von 30 Minuten zu jedem Zeitstempel?

Erdbeere
quelle
1
Stimmen diese Zeitstempel mit ihrem Erstellungsdatum überein? ist es dasselbe wie ls --full-time?
Sergiy Kolodyazhnyy
1
Nein, die Zeitstempel unterscheiden sich vom Erstellungs- / Änderungsdatum. Die Zeitstempel basieren auf der Zeit, zu der die Daten gemessen wurden.
Strawberrie
1
Da diese Zeitstempel benutzerdefiniert sind, ist ein Skript erforderlich, das das Hinzufügen von 30 Minuten zum Datum berechnen muss. Es wird keinen einfachen Befehl geben.
Daher
1
Gibt es Zeitstempel, die kurz vor Mitternacht liegen, sodass das Hinzufügen von 30 Minuten dazu führen kann, dass ein Tag um eins geändert werden muss?
Sergiy Kolodyazhnyy
1
Welches Format haben Stunden? 12 dann 1,2,3 (12-Stunden-Format) oder 12 bis 13 bis 14, 15. . . 23, 00 (24-Stunden-Format)?
Sergiy Kolodyazhnyy

Antworten:

6

Verwenden von 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')ändert das aktuelle Verzeichnis in das Verzeichnis, das die .datDateien enthält. Durch /path/to/dirden tatsächlichen Pfad ersetzen .

  • glob.glob('*.dat') findet die Dateien, die auf enden .dat

  • ini_timeDie Variable schneidet zunächst mithilfe des reModuls die Datums- und Uhrzeitangabe aus dem ursprünglichen Dateinamen aus und sortiert dann aus, welcher Eintrag was in der herausgenommenen Zeichenfolge darstellt, damit wir die erforderliche Zeit hinzufügen können

  • fin_timeenthält die resultierende Zeit, dh ini_timeplus 30 Minuten

  • os.rename benennt die Datei entsprechend um.

Beachten Sie auch, dass bei aufeinanderfolgenden Dateinamen (die sich um 30 Minuten unterscheiden) die umbenannte Datei die nächste überschreibt. Daher ist es besser, die Sekunden zum umbenannten Dateinamen hinzuzufügen, damit sie sicher bleibt. Andernfalls müssen Sie die umbenannten Dateien in einem anderen Verzeichnis speichern und später durch die ursprünglichen ersetzen.

heemayl
quelle
Du und Python, eine große Liebe. =) +1
AB
Sie sollten die Zeichenfolge nicht Filename_in der Umbenennungsmethode verwenden.
AB
@AB Warum ist das so? (+1 auch für Sie)
heemayl
Wissen Sie, warum nach dem Ausführen des Python-Skripts einige Dateien fehlen? Der Zeitstempel für jede Datei beträgt 30 Minuten. Im Folgenden ist der Ausgang für den ersten Dateinamen: 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
Strawberrie
@strawberrie Ich weiß nicht .. es hat es getestet und funktioniert gut für mich ohne Probleme .. haben Sie das Skript ausgeführt, das das /path/to/filedurch den vollständigen Pfad zum Verzeichnis ersetzt?
Heemayl
2

Mit bashwerden die umbenannten Dateien in einem neuen Unterordner gespeichert renamed.

Starten Sie das Skript in dem Ordner, in dem sich die Dateien befinden.

#!/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

Beispielausgabe:

% 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
AB
quelle
@strawberrie die umbenannten Dateien werden jetzt in einem Unterordner abgelegtrenamed
AB
Gute Idee, umbenannte Dateien in einem zusätzlichen Ordner zu speichern. Für den Fall, dass etwas schief geht, hat OP noch Originale. Gutes Denken, daher +1
Sergiy Kolodyazhnyy
Danke @AB Ich habe die folgende Fehlermeldung erhalten, nachdem ich Ihr Skript ausgeführt habe: TimeChange.sh: 21: TimeChange.sh: Ungültige Ersetzung Mein tatsächlicher Dateiname oder das feste Präfix vor dem Zeitstempel lautet FileName_123.Data_YYYY_MM_DD_HHMM.dat
Strawberrie
Per Definition ist für FileName_123.Data_YYYY_MM_DD_HHMM.datdas Teil .Data_YYYY_MM_DD_HHMM.datdie Erweiterung. Und ist daher FileName_123kein gültiger Zeitstempel.
AB
@ Strawberrie Ich habe mein Skript geändert
AB
1

SKRIPT

Dies ist die bearbeitete Version meines ursprünglichen Skripts. OP lieferte ursprünglich keine vollständigen Informationen zum Namensformat. Dieses Skript passt sich an das in den Kommentaren erwähnte OP an, das die korrekte Benennung der Datei war.

* Technische Hinweise: *

In diesem Skript trennen wir den Dateinamen mit awk in 6 separate Felder, wobei der Unterstrich als Feldtrennzeichen dient. Die ersten beiden Felder $ 1 und $ 2 werden als statische Textzeichenfolge betrachtet. Die Felder 3,4,5 und 6 sind der Zeitstempel, zu dem die OP-Daten abgetastet wurden, nicht das Erstellungsdatum der Datei im Dateisystem.

Die Variable COPYDIR enthält den Namen des neuen Verzeichnisses, in das Dateien mit aktualisiertem Zeitstempel verschoben werden. Wir erstellen dieses Verzeichnis im aktuellen Arbeitsverzeichnis mitmkdir $COPYDIR

Die Variablen TEXTSTRING und DATESTRING enthalten jeweils statischen Text und Zeitstempel. In der Beispielausgabe unten habe ich zwei verschiedene Zeichenfolgen verwendet, um zu beweisen, dass das Skript funktioniert, unabhängig davon, welchen Text die ersten beiden Felder enthalten.

NEWEPOCHTIME ist eine Variable, die berechneten neuen Zeitstempel im Unix-Epochenformat enthält. NEWDATE ist eine Variable, die den konvertierten Zeitstempel von der Unix-Epoche in das Format JJJJ-MM-TT HH: MM enthält. NEWAPPEND ist der tatsächliche Zeitstempel, der der Datei im gewünschten OP-Format JJJJ_MM_TT_HHMM hinzugefügt wird.

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat kopiert die alte Datei mit dem aktualisierten Datenstempel in das Verzeichnis "convert_files" (anstatt sie zu verschieben, um Datenverlust zu vermeiden).

Beachten Sie , dass das Skript funktioniert, solange das Namensformat wirklich eingehalten wird, dh alle Dateien haben wirklich das 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 IN AKTION

Der Demonstrationsbalg ist eine direkte Kopie von meinem Terminal. Beachten Sie, dass ich in den ersten beiden Feldern Originaldateien mit zwei verschiedenen Zeichenfolgen erstellt habe. Dieses Skript sollte also funktionieren, egal was am Anfang des Dateinamens steht, solange es wirklich nur zwei durch Unterstriche getrennte Zeichenfolgen gibt

Das Skript wurde benannt, notes-conversionweil ich das Skript aus den Notizen entwickelt habe, die ich während der Arbeit an dieser Frage gemacht habe.

Beachten Sie, dass Dateinamen mit dem HHMM-Teil 2345 (15 Minuten vor Mitternacht) auf 0015 und der DD-Teil auf den nächsten Tag aktualisiert werden. 24-Stunden-Format erhalten.

Da for loop nur nach .datDateien sucht , vermeiden wir außerdem das Umbenennen anderer Dateien oder Verzeichnisse, die sich möglicherweise im Arbeitsverzeichnis befinden, und vermeiden so potenziellen Datenverlust. Im folgenden Beispiel enthält das Originalverzeichnis 11 Elemente, von denen 3 *.txtDateien zum Testen sind. Daher arbeiten wir nur mit 8 .datDateien. In dem Verzeichnis, in das aktualisierte Dateien verschoben werden, werden 8 Dateien angezeigt, alle .datund keine anderen Dateien. Daten sind sicher, Skript macht seinen Job.

[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 $ 

ERKLÄRUNG (vom ursprünglichen Beitrag)

*) Heute habe ich erfahren, dass Unix-Linux-Systeme die Zeit in der Epoche zählen oder einfach Sekunden eingeben.

*) Das Skript nimmt jeden Dateinamen, extrahiert das Datum, konvertiert es in eine Epoche, fügt 1800 Sekunden hinzu (was genau 30 Minuten entspricht) und speichert die Datei mit einem neuen Zeitstempel.

*) Dieses Skript adressiert, was OP wollte - ändern Sie den Zeitstempel im Dateinamen, nicht die Erstellungszeit der Datei selbst

Benutztes Werkzeug:

  • Ubuntu 15.04

  • GNU Bash 4.3.30

  • GNU awk 4.1.1

  • Datum (GNU Coreutils) 8.23

Sergiy Kolodyazhnyy
quelle
übrigens ls | wc -l vor gibt 36 Dateien, und nach dem Skript auch 36 Dateien, keine fehlen
Sergiy Kolodyazhnyy
Der Grund, warum ich die Datei stat -c% n verwende, ist, dass das Parsen der Ausgabe von ls im Allgemeinen keine gute Idee ist. Einige Leute benutzen findBefehle, was auch gut ist.
Sergiy Kolodyazhnyy
Danke @Serg. Ich weiß nicht, warum ich nur 2 von 727 Dateien im Ordner gelassen habe, nachdem ich Ihr Skript ausgeführt habe ...
Strawberrie
Gab es einen Unterschied zwischen den tatsächlichen Dateinamen und dem von Ihnen veröffentlichten Beispiel?
Sergiy Kolodyazhnyy
Haben Sie auch die erste Zeile im "Skript in Aktion" ausgeführt? Der rm * diente dazu, mein eigenes Verzeichnis zu bereinigen und dann eine Reihe von Testdateien mit unterschiedlichen Datumsangaben in Dateinamen zu erstellen. Sie sollten das nicht ausführen
Sergiy Kolodyazhnyy
-1

Sie können diesen Code verwenden, um das zu tun, was Sie benötigen

  1. Sie sollten ein Backup erstellen und zuerst den Code testen, um festzustellen, ob er für Ihren Fall geeignet ist
  2. Sie verwenden das 24H-Format
  3. Nach 23:29 werden keine Dateien mehr benannt (wenn Sie nach dieser Zeit Dateien haben, sollte der Code geändert werden, um auch das Datum zu ändern).

Der Code lautet:

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 ;

So funktioniert es: Der Code überprüft den Minutenteil im Dateinamen. MMWenn er kleiner als 30 ist, addiert er 30 zu dem, MMwenn er 30 oder mehr entspricht, addiert er 1 Stunde zu dem HHTeil im Namen und zieht 30 Minuten von dem ab MMTeil des Namens

Fat Mind
quelle
Für Abstimmungsergebnisse bitte den Grund mitteilen.
Fat Mind