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?
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?
Antworten:
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 .dat
Dateien enthält. Durch /path/to/dir
den tatsächlichen Pfad ersetzen .
glob.glob('*.dat')
findet die Dateien, die auf enden .dat
ini_time
Die Variable schneidet zunächst mithilfe des re
Moduls 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_time
enthält die resultierende Zeit, dh ini_time
plus 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.
Filename_
in der Umbenennungsmethode verwenden.
/path/to/file
durch den vollständigen Pfad zum Verzeichnis ersetzt?
Mit bash
werden 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
renamed
FileName_123.Data_YYYY_MM_DD_HHMM.dat
das Teil .Data_YYYY_MM_DD_HHMM.dat
die Erweiterung. Und ist daher FileName_123
kein gültiger Zeitstempel.
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.dat
Format.
#!/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-conversion
weil 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 .dat
Dateien 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 *.txt
Dateien zum Testen sind. Daher arbeiten wir nur mit 8 .dat
Dateien. In dem Verzeichnis, in das aktualisierte Dateien verschoben werden, werden 8 Dateien angezeigt, alle .dat
und 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
find
Befehle, was auch gut ist.
Sie können diesen Code verwenden, um das zu tun, was Sie benötigen
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. MM
Wenn er kleiner als 30 ist, addiert er 30 zu dem, MM
wenn er 30 oder mehr entspricht, addiert er 1 Stunde zu dem HH
Teil im Namen und zieht 30 Minuten von dem ab MM
Teil des Namens
ls --full-time
?