Tengo los nombres de los archivos de datos en orden cronológico:
FileName_YYYY_MM_DD_HHMM.dat
¿Hay algún comando para agregar 30 minutos a cada marca de tiempo?
Tengo los nombres de los archivos de datos en orden cronológico:
FileName_YYYY_MM_DD_HHMM.dat
¿Hay algún comando para agregar 30 minutos a cada marca de tiempo?
Respuestas:
Utilizando 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')
cambiará el directorio actual al directorio que contiene los .dat
archivos. Reemplazar /path/to/dir
con la ruta real.
glob.glob('*.dat')
encontrará los archivos que terminan en .dat
ini_time
La variable al principio recortará la fecha y hora del nombre del archivo original usando el re
módulo y luego clasificará qué entrada representa qué en la cadena se extrae para que podamos agregar el tiempo requerido a esto
fin_time
contendrá el tiempo resultante, es decir, ini_time
más 30 minutos
os.rename
cambiará el nombre del archivo en consecuencia.
También tenga en cuenta que, con los nombres de archivo sucesivos (diferidos en 30 minutos), el archivo renombrado sobrescribirá el siguiente, por lo tanto, es mejor agregar los segundos al nombre del archivo renombrado para que permanezca seguro. De lo contrario, debe guardar los archivos renombrados en un directorio diferente y luego reemplazarlos con los originales más adelante.
Filename_
en el método de cambio de nombre.
/path/to/file
con la ruta completa al directorio?
Utilizando bash
, los archivos renombrados están en una nueva subcarpeta renamed
.
Inicie el script en la carpeta donde se encuentran los archivos.
#!/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
salida de ejemplo:
% 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
es la extensión. Y, por FileName_123
lo tanto, no es una marca de tiempo válida.
GUIÓN
Esta es la versión editada de mi guión original. OP originalmente no proporcionó información completa sobre el formato de nombres. Este script se adapta a lo que OP mencionó en los comentarios fue el nombre correcto del archivo.
*Notas técnicas: *
En este script separamos el nombre del archivo en 6 campos separados usando awk, con guión bajo como delimitador de campo. Los primeros dos campos, $ 1 y $ 2 se consideran cadenas de texto estático. Los campos 3,4,5 y 6 son la marca de tiempo en la que se muestrearon los datos de OP, no la fecha de creación del archivo en el sistema de archivos.
La variable COPYDIR contiene el nombre del nuevo directorio donde irán los archivos con marca de tiempo actualizada. Creamos ese directorio en el directorio de trabajo actual conmkdir $COPYDIR
Las variables TEXTSTRING y DATESTRING contienen texto estático y marca de tiempo respectivamente. En la salida de muestra a continuación, he usado dos cadenas diferentes para demostrar que el script funcionará independientemente de qué texto contengan los dos primeros campos.
NEWEPOCHTIME es una variable que contiene la nueva marca de tiempo calculada en formato de época unix. NEWDATE es una variable que contiene la marca de tiempo convertida de unix epoch al formato AAAA-MM-DD HH: MM. NEWAPPEND es la marca de tiempo real que se agregará al archivo en el formato deseado de OP AAAA_MM_DD_HHMM.
cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat
copia el archivo antiguo en el directorio "convert_files" (en lugar de moverlo, para evitar la pérdida de datos) con el sello de datos actualizado.
Aviso , el guión va a funcionar siempre y cuando el formato de nombre es muy seguido, es decir, todos los archivos están realmente tienen 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
GUIÓN EN ACCIÓN
La demostración a continuación es una copia directa desde mi terminal. Tenga en cuenta que he creado archivos originales con dos cadenas diferentes en los dos primeros campos. Por lo tanto, este script debería funcionar sin importar el principio del nombre del archivo, siempre que solo haya dos cadenas separadas por un guión bajo
El guión fue nombrado notes-conversion
porque desarrollé el guión a partir de las notas que tomé mientras trabajaba en esta pregunta.
Observe que los nombres de archivo que tienen la parte HHMM como 2345 (que es 15 minutos antes de la medianoche) se actualizan a 0015, y la parte DD se actualiza al día siguiente. Formato de 24 horas preservado.
Además, debido a que for loop solo busca .dat
archivos, evitamos cambiar el nombre de otros archivos o directorios que pueden estar en el directorio de trabajo, evitando así cualquier pérdida potencial de datos. En el siguiente ejemplo, el directorio original contiene 11 elementos, 3 de los cuales son *.txt
archivos para probar, por lo que solo trabajamos con 8 .dat
archivos. En el directorio donde van los archivos actualizados, vemos 8 archivos, todos .dat
y ningún otro archivo. Los datos están seguros, el script hace su trabajo.
[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 $
EXPLICACIÓN (de la publicación original)
*) Hoy he aprendido que los sistemas Unix-Linux cuentan el tiempo en la época de la época , o simplemente ponen segundos.
*) el script toma cada nombre de archivo, extrae la fecha, la convierte en época, agrega 1800 segundos (que son exactamente 30 minutos) y guarda el archivo con una nueva marca de tiempo.
*) Este script aborda lo que OP quería: cambiar la marca de tiempo en el nombre del archivo, no actualizar el tiempo de creación del archivo en sí
Herramientas utilizadas:
ubuntu 15.04
GNU bash 4.3.30
GNU awk 4.1.1
fecha (GNU coreutils) 8.23
find
comandos, lo que también es bueno.
Puede usar este código para hacer lo que necesita asumiendo
el código es:
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 ;
Cómo funciona:
el código verificará la parte de minutos en el nombre del archivo, MM
luego, si es inferior a 30, agregará 30 a MM
si es igual a 30 o más, agregará 1 hora a la HH
parte en el nombre y deducirá 30 minutos del MM
parte del nombre
ls --full-time
?