Eu tenho os nomes dos arquivos dat em ordem cronológica:
FileName_YYYY_MM_DD_HHMM.dat
Existe algum comando para adicionar 30 minutos a cada carimbo de data / hora?
Eu tenho os nomes dos arquivos dat em ordem cronológica:
FileName_YYYY_MM_DD_HHMM.dat
Existe algum comando para adicionar 30 minutos a cada carimbo de data / hora?
Respostas:
Usando 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')
alterará o diretório atual para o diretório que contém os .dat
arquivos. Substitua /path/to/dir
pelo caminho real.
glob.glob('*.dat')
encontrará os arquivos que terminam em .dat
ini_time
A variável primeiro cortará a data e hora do nome do arquivo original usando o re
módulo e depois classificará qual entrada representa o que na string removida, para que possamos adicionar o tempo necessário a esse
fin_time
conterá o tempo resultante, ou seja, ini_time
mais 30 minutos
os.rename
renomeará o arquivo de acordo.
Observe também que, com nomes de arquivos sucessivos (diferidos por 30 minutos), o arquivo renomeado substituirá o próximo, portanto, é melhor adicionar os segundos ao nome do arquivo renomeado para que ele permaneça seguro. Caso contrário, você precisará salvar os arquivos renomeados em um diretório diferente e substituí-los pelos originais mais tarde.
Filename_
no método renomear.
/path/to/file
com o caminho completo para o diretório?
Usando bash
, os arquivos renomeados estão em uma nova subpasta renamed
.
Inicie o script na pasta em que os arquivos estão localizados.
#!/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
saída de exemplo:
% 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
a parte .Data_YYYY_MM_DD_HHMM.dat
é a extensão. E, portanto, FileName_123
não é um carimbo de data / hora válido.
ROTEIRO
Esta é a versão editada do meu script original. O OP originalmente não forneceu informações completas sobre o formato de nomeação. Esse script se adapta ao OP mencionado nos comentários como a nomeação correta do arquivo.
* Notas técnicas: *
Neste script, separamos o nome do arquivo em 6 campos separados, usando awk, com sublinhado como delimitador de campo. Os dois primeiros campos, $ 1 e $ 2, são considerados sequência de texto estática. Os campos 3,4,5 e 6 são o registro de data e hora em que os dados do OP foram amostrados, não a data de criação do arquivo no sistema de arquivos.
A variável COPYDIR contém o nome do novo diretório para onde os arquivos com registro de data e hora atualizados irão. Criamos esse diretório no diretório de trabalho atual commkdir $COPYDIR
As variáveis TEXTSTRING e DATESTRING mantêm o texto estático e o carimbo de data / hora respectivamente. No exemplo de saída abaixo, usei duas cadeias diferentes para provar que o script funcionará independentemente do texto que os dois primeiros campos contenham.
NEWEPOCHTIME é uma variável que mantém o novo registro de data e hora calculado no formato de época unix. NEWDATE é uma variável que mantém o registro de data e hora convertido da época unix para o formato AAAA-MM-DD HH: MM. NEWAPPEND é o carimbo de data / hora real que será adicionado ao arquivo no formato YYYY_MM_DD_HHMM do OP desejado.
cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat
copia o arquivo antigo no diretório "convert_files" (em vez de mover, para evitar a perda de dados) com o datastamp atualizado.
Aviso , o script irá funcionar, desde que o formato de nomeação é realmente seguido, ou seja, todos os arquivos são realmente tem 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 EM AÇÃO
A demonstração abaixo é uma cópia direta do meu terminal. Observe que eu criei arquivos originais com duas cadeias diferentes nos dois primeiros campos. Portanto, esse script deve funcionar, não importa o que está no início do nome do arquivo, desde que haja realmente apenas duas cadeias separadas por sublinhado
O script foi nomeado notes-conversion
porque eu desenvolvi o script a partir das anotações que fiz enquanto trabalhava nesta questão.
Observe que os nomes de arquivos que possuem parte do HHMM como 2345 (15 minutos antes da meia-noite) são atualizados para 0015 e a parte DD é atualizada para o dia seguinte. Formato de 24 horas preservado.
Além disso, como o loop for procura apenas .dat
arquivos, evitamos renomear outros arquivos ou diretórios que possam estar no diretório ativo, evitando possíveis perdas de dados. No exemplo abaixo, o diretório original contém 11 itens, 3 dos quais são *.txt
arquivos para teste, portanto, trabalhamos apenas com 8 .dat
arquivos. No diretório para onde os arquivos atualizados vão, vemos 8 arquivos, todos .dat
e nenhum outro arquivo. Os dados são seguros, o script faz seu trabalho.
[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 $
EXPLICAÇÃO (da postagem original)
*) Hoje eu aprendi que os sistemas Unix-Linux contam tempo em época , ou simplesmente colocam segundos.
*) o script pega cada nome de arquivo, extrai data, converte-o em época, adiciona 1800 segundos (que são exatamente 30 minutos) e salva o arquivo com o novo timestamp.
*) Esse script aborda o que o OP queria - altere o carimbo de data / hora no nome do arquivo, não atualiza o horário de criação do próprio arquivo
Ferramentas usadas:
ubuntu 15.04
GNU bash 4.3.30
GNU awk 4.1.1
data (GNU coreutils) 8.23
find
comando, o que também é bom.
Você pode usar esse código para fazer o que você precisa assumindo
o código é:
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 ;
Como funciona:
o código verifica a parte dos minutos no nome do arquivo MM
e, se for menor que 30, adiciona 30 ao MM
se for igual a 30 ou mais, adiciona 1 hora à HH
parte no nome e deduz 30 minutos do MM
parte do nome
ls --full-time
?