Como posso alterar o carimbo de data / hora do nome do arquivo?

8

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?

strawberrie
fonte
1
esses carimbos de data e hora são iguais à data de criação? é o mesmo que ls --full-time?
Sergiy Kolodyazhnyy
1
Não, os carimbos de data e hora são diferentes da data de criação / modificação. Os registros de data e hora são baseados no horário em que os dados foram medidos.
strawberrie
1
Veja, como esses carimbos de data / hora são personalizados, será necessário um script, que precisa calcular a adição de 30 minutos à data, não haverá nenhum comando simples. por isso pode demorar um pouco para que as pessoas respondem
Sergiy Kolodyazhnyy
1
existem carimbos de data e hora próximos da meia-noite, de modo que adicionar 30 minutos possa resultar na necessidade de alterar um dia por um?
Sergiy Kolodyazhnyy
1
que formato são as horas? 12 e 1,2,3 (formato de 12 horas) ou 12 a 13 a 14, 15. . . 23, 00 (formato de 24 horas)?
Sergiy Kolodyazhnyy

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')alterará o diretório atual para o diretório que contém os .datarquivos. Substitua /path/to/dirpelo caminho real.

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

  • ini_timeA variável primeiro cortará a data e hora do nome do arquivo original usando o remódulo e depois classificará qual entrada representa o que na string removida, para que possamos adicionar o tempo necessário a esse

  • fin_timeconterá o tempo resultante, ou seja, ini_timemais 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.

heemail
fonte
Você e python, um grande amor. =) +1
AB
Você não deve usar a string Filename_no método renomear.
AB
@AB Por que isso? (+1 para você também)
heemayl
Você sabe por que alguns arquivos estão faltando após a execução do script python? O registro de data e hora de cada arquivo tem 30 minutos de diferença. Abaixo está a saída para os primeiros nomes: Filename_2011_01_11_1630.dat Filename_2011_01_11_1830.dat Filename_2011_01_11_1900.dat Filename_2011_01_11_2030.dat Filename_2011_01_11_2100.dat
strawberrie
@ strawberrie eu não sei .. ele foi testado e está funcionando bem para mim sem nenhum problema .. você executou o script substituindo o /path/to/filecom o caminho completo para o diretório?
Hemayl # 16/15
2

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
AB
fonte
@strawberrie os arquivos renomeados estão agora colocados em uma pasta subrenamed
AB
boa idéia para salvar arquivos renomeados em uma pasta extra. Caso algo dê errado, o OP ainda possui originais. Bom pensamento, daí +1
Sergiy Kolodyazhnyy 16/05
Graças @AB eu tenho o seguinte erro depois de executar o script: TimeChange.sh: 21: TimeChange.sh: Bad substituição Meu nome real ou o prefixo fixado antes do timestamp é como FileName_123.Data_YYYY_MM_DD_HHMM.dat
strawberrie
Por definição, FileName_123.Data_YYYY_MM_DD_HHMM.data parte .Data_YYYY_MM_DD_HHMM.daté a extensão. E, portanto, FileName_123não é um carimbo de data / hora válido.
AB
@strawberrie Mudei meu script
AB
1

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.datformato.

#!/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-conversionporque 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 .datarquivos, 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 *.txtarquivos para teste, portanto, trabalhamos apenas com 8 .datarquivos. No diretório para onde os arquivos atualizados vão, vemos 8 arquivos, todos .date 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

Sergiy Kolodyazhnyy
fonte
a propósito, sl | wc -l antes dá 36 arquivos, e depois script também 36 arquivos, nenhum faltando
Sergiy Kolodyazhnyy
Além disso, o motivo pelo qual eu uso o arquivo stat -c% n é porque analisar a saída de ls geralmente não é uma boa ideia. Algumas pessoas usam o findcomando, o que também é bom.
Sergiy Kolodyazhnyy
Obrigado @Serg. Eu não sei por que eu só deixou 2 de 727 arquivos deixados na pasta depois de executar o script ...
strawberrie
Houve alguma diferença entre os nomes dos arquivos reais e o exemplo que você postou?
Sergiy Kolodyazhnyy
Além disso, você executou a primeira linha no "Script em ação"? o rm * era para limpar meu próprio diretório e criar vários arquivos de teste com datas diferentes nos nomes dos arquivos. Você não deveria executar isso #
Sergiy Kolodyazhnyy 16/05
-1

Você pode usar esse código para fazer o que você precisa assumindo

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

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 MMe, se for menor que 30, adiciona 30 ao MMse for igual a 30 ou mais, adiciona 1 hora à HHparte no nome e deduz 30 minutos do MMparte do nome

Mente Gorda
fonte
para baixo eleitor, por favor notifique o motivo?
Fat Mind