Ho i nomi dei file di dati in ordine cronologico:
FileName_YYYY_MM_DD_HHMM.dat
Esistono comandi per aggiungere 30 minuti a ciascun timestamp?
Ho i nomi dei file di dati in ordine cronologico:
FileName_YYYY_MM_DD_HHMM.dat
Esistono comandi per aggiungere 30 minuti a ciascun timestamp?
Risposte:
Utilizzando 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')
cambierà la directory corrente nella directory contenente i .dat
file. Sostituisci /path/to/dir
con il percorso effettivo.
glob.glob('*.dat')
troverà i file che finiscono in .dat
ini_time
la variabile taglierà prima la data e l'ora dal nome del file originale usando il re
modulo e quindi ordinerà quale voce rappresenta ciò che nella stringa viene tolta in modo da poter aggiungere il tempo richiesto a questo
fin_time
conterrà il tempo risultante, ovvero ini_time
più 30 minuti
os.rename
rinominerà il file di conseguenza.
Si noti inoltre che, con nomi di file successivi (differiti di 30 minuti) il file rinominato sovrascriverà il successivo, quindi è meglio aggiungere i secondi al nome del file rinominato in modo che rimanga sicuro. In caso contrario, è necessario salvare i file rinominati in una directory diversa e sostituirli successivamente con quelli originali.
Filename_
nel metodo di ridenominazione.
/path/to/file
con il percorso completo della directory?
Utilizzando bash
, i file rinominati si trovano in una nuova sottocartella renamed
.
Avviare lo script nella cartella in cui si trovano i file.
#!/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
esempio di output:
% 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
la parte .Data_YYYY_MM_DD_HHMM.dat
è l'estensione. E quindi FileName_123
non è un timestamp valido.
SCRIPT
Questa è la versione modificata del mio script originale. OP inizialmente non ha fornito informazioni complete sul formato di denominazione. Questo script si adatta a ciò che OP menzionato nei commenti era la denominazione corretta del file.
* Note tecniche: *
In questo script separiamo il nome file in 6 campi separati usando awk, con trattino basso come delimitatore di campo. I primi due campi, $ 1 e $ 2 sono considerati stringhe di testo statiche. I campi 3,4,5 e 6 sono il timestamp in cui sono stati campionati i dati di OP, non la data di creazione del file sul filesystem.
La variabile COPYDIR contiene il nome della nuova directory in cui andranno i file con data e ora aggiornata. Creiamo quella directory nella directory di lavoro corrente conmkdir $COPYDIR
Le variabili TEXTSTRING e DATESTRING mantengono rispettivamente il testo statico e il timestamp. Nel seguente esempio di output ho usato due stringhe diverse per dimostrare che lo script funzionerà indipendentemente dal testo contenuto nei primi due campi.
NEWEPOCHTIME è una variabile che contiene il nuovo timestamp calcolato in formato epoca unix. NEWDATE è una variabile che contiene il timestamp convertito dall'epoca unix al formato AAAA-MM-GG HH: MM. NEWAPPEND è il timestamp effettivo che verrà aggiunto al file nel formato AAAA_MM_DD_HHMM desiderato dell'OP.
cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat
copia il vecchio file nella directory "converter_files" (invece di spostarlo, per evitare la perdita di dati) con il datastamp aggiornato.
Si noti che lo script funzionerà fino a quando il formato di denominazione è realmente seguito, ovvero tutti i file hanno davvero un SomeText_123.Data_YYYY_MM_DD_HHMM.dat
formato.
#!/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 AZIONE
Il muggito della dimostrazione è una copia diretta dal mio terminale. Si noti che ho creato file originali con due stringhe diverse nei primi due campi. Quindi questo script dovrebbe funzionare indipendentemente da ciò che è all'inizio del nome del file, purché in realtà ci siano solo due stringhe separate da un trattino basso
La sceneggiatura è stata nominata notes-conversion
perché ho sviluppato la sceneggiatura dalle note che ho preso mentre lavoravo su questa domanda.
Si noti che i nomi di file che hanno parte HHMM come 2345 (ovvero 15 minuti prima di mezzanotte) vengono aggiornati a 0015 e la parte DD viene aggiornata al giorno successivo. Formato 24 ore conservato.
Inoltre, poiché for loop cerca solo i .dat
file, evitiamo di rinominare altri file o directory che potrebbero trovarsi nella directory di lavoro, evitando così qualsiasi potenziale perdita di dati. Nell'esempio seguente, la directory originale contiene 11 elementi, 3 dei quali sono *.txt
file per il test, quindi lavoriamo solo con 8 .dat
file. Nella directory in cui vanno i file aggiornati, vediamo 8 file, tutti .dat
e nessun altro file. I dati sono al sicuro, lo script fa il suo lavoro.
[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 $
SPIEGAZIONE (dalla posta originale)
*) Oggi ho imparato che i sistemi Unix-Linux contano il tempo in tempo di epoca , o semplicemente mettono secondi.
*) lo script prende ogni nome di file, estrae la data, lo converte in epoca, aggiunge 1800 secondi (che è esattamente 30 minuti) e salva il file con un nuovo timestamp.
*) Questo script si rivolge a ciò che OP voleva: modificare la data / ora nel nome file, non aggiornare l'ora di creazione del file stesso
Strumenti utilizzati:
ubuntu 15.04
GNU bash 4.3.30
GNU awk 4.1.1
data (GNU coreutils) 8.23
find
comando, il che è anche buono.
È possibile utilizzare questo codice per fare ciò che è necessario assumere
il codice è:
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 ;
Come funziona:
il codice controllerà la parte dei minuti nel nome del file, MM
quindi se è inferiore a 30 ne aggiungerà 30 MM
se è uguale a 30 o più aggiungerà 1 ora alla HH
parte nel nome e detrarrà 30 minuti dal MM
parte del nome
ls --full-time
?