Como posso alterar o registro de data e hora do nome do arquivo?

8

Eu tenho nomes de arquivos de dados em ordem cronológica:

FileName_YYYY_MM_DD_HHMM.dat

Existe algum comando para adicionar 30 minutos a cada timestamp?

    
por strawberrie 16.05.2015 / 19:40

4 respostas

6

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') mudará o diretório atual para o diretório que contém os arquivos .dat . Substitua /path/to/dir pelo caminho real.

  • glob.glob('*.dat') encontrará os arquivos que terminam em .dat

  • A variável
  • ini_time primeiro cortará a data e hora do nome do arquivo original usando re module e, em seguida, classificará qual entrada representa o que na string é retirada para que possamos adicionar o tempo necessário para isso

  • 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 sobrescreverá 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, em seguida, substituí-los pelos originais posteriormente.

    
por heemayl 16.05.2015 / 21:41
2

Usando bash , os arquivos renomeados estão em uma nova subpasta renamed .

Inicie o script na pasta onde 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
Exemplo de saída

:

% 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
    
por A.B. 16.05.2015 / 22:02
1

SCRIPT

Esta é a versão editada do meu script original. OP originalmente não forneceu informações completas sobre o formato de nomenclatura. Este script se adapta ao que OP mencionou nos comentários foi a nomenclatura correta do arquivo.

* Notas técnicas: *

Neste script separamos o nome do arquivo em 6 campos separados usando o awk, com sublinhado como delimitador de campo. Primeiros dois campos, $ 1 e $ 2 são considerados string de texto estático. 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.

Variável COPYDIR contém o nome do novo diretório no qual os arquivos com o registro de data e hora atualizado serão enviados. Criamos esse diretório no diretório de trabalho atual com mkdir $COPYDIR

Variáveis TEXTSTRING e DATESTRING mantêm o texto estático e o timestamp respectivamente. Na saída de amostra abaixo, usei duas strings diferentes para provar que o script funcionará, independentemente do texto que os dois primeiros campos contêm.

NEWEPOCHTIME é uma variável que contém um novo timestamp calculado no formato unix epoch. NEWDATE é uma variável que armazena timestamp do formato unix epoch para YYYY-MM-DD HH: MM. NEWAPPEND é o timestamp real que será adicionado ao arquivo no formato YYYY_MM_DD_HHMM desejado do OP.

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat copia o arquivo antigo para o diretório "converted_files" (em vez de mover, para evitar perda de dados) com o datastamp atualizado.

Aviso , o script funcionará enquanto o formato de nomenclatura for realmente seguido, ou seja, todos os arquivos realmente têm 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 EM AÇÃO

A demonstração abaixo é cópia direta do meu terminal. Observe que eu criei arquivos originais com duas strings diferentes nos dois primeiros campos. Portanto, este script deve funcionar não importa o que esteja no início do nome do arquivo, desde que haja apenas duas strings separadas por sublinhado

O script recebeu o nome notes-conversion porque desenvolvi o script a partir das anotações que fiz enquanto trabalhava nessa questão.

Observe que os nomes de arquivos que têm a parte HHMM como 2345 (que é de 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 apenas procura por .dat arquivos, evitamos renomear outros arquivos ou diretórios que possam estar no diretório de trabalho, evitando assim qualquer possível perda de dados. No exemplo abaixo, o diretório original contém 11 itens, dos quais 3 são *.txt de arquivos para teste, portanto, só trabalhamos com 8% de arquivos.dat. 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 o 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 aprendi que os sistemas Unix-Linux contam o tempo em Tempo da epoch , ou simplesmente colocam segundos.

*) o script pega cada nome de arquivo, extrai data, converte em epoch, adiciona 1800 segundos (que são exatamente 30 minutos) e salva o arquivo com um novo timestamp.

*) Este script aborda o que o OP queria - altere o timestamp no nome do arquivo, não atualize o tempo de criação do próprio arquivo

Ferramentas usadas:

  • ubuntu 15.04

  • bash do GNU 4.3.30

  • GNU awk 4.1.1

  • date (GNU coreutils) 8.23

por Sergiy Kolodyazhnyy 16.05.2015 / 23:00
-1

Você pode usar este código para fazer o que você precisa assumir

  1. você deve fazer o backup e testar o código primeiro para ver se ele é adequado para o seu caso
  2. você está usando o formato 24H
  3. nenhum arquivo será nomeado após 23:29 (se você ter arquivos após esse tempo, o código deve ser modificado para alterar a data também)

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 verificará a parte dos minutos no nome do arquivo MM e, se for menor que 30, adicionará 30 ao MM , se for igual a 30 ou mais, adicionará 1 hora à parte HH no nome e deduzir 30 minutos da parte MM do nome

    
por Fat Mind 17.05.2015 / 00:49