Come posso modificare il timestamp del nome file?


8

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?


1
quei timestamp coincidono con la data di creazione? è lo stesso di ls --full-time?
Sergiy Kolodyazhnyy,

1
No, i timestamp sono diversi rispetto alla data di creazione / modifica. I timestamp si basano sul tempo di misurazione dei dati.
Strawberrie,

1
Vedi, dato che quei timestamp sono personalizzati, richiederà uno script, che deve calcolare aggiungendo 30 minuti alla data, non ci sarà alcun semplice comando. quindi potrebbe essere necessario un po 'di tempo prima che le persone rispondano
Sergiy Kolodyazhnyy,

1
ci sono timestamp vicini a mezzanotte, in modo tale che l'aggiunta di 30 minuti potrebbe comportare la necessità di cambiare un giorno di uno?
Sergiy Kolodyazhnyy,

1
che formato sono le ore? 12 quindi 1,2,3 (formato 12 ore) o 12-13 a 14, 15. . . 23, 00 (formato 24 ore)?
Sergiy Kolodyazhnyy,

Risposte:


6

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 .datfile. Sostituisci /path/to/dircon il percorso effettivo.

  • glob.glob('*.dat') troverà i file che finiscono in .dat

  • ini_timela variabile taglierà prima la data e l'ora dal nome del file originale usando il remodulo e quindi ordinerà quale voce rappresenta ciò che nella stringa viene tolta in modo da poter aggiungere il tempo richiesto a questo

  • fin_timeconterrà il tempo risultante, ovvero ini_timepiù 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.


Tu e Python, un grande amore. =) +1
AB

Non utilizzare la stringa Filename_nel metodo di ridenominazione.
AB,

@AB Perché è quello? (+1 anche per te)
heemayl

Sai perché mi mancano alcuni file dopo aver eseguito lo script Python? Il timestamp per ciascun file ha una differenza di 30 minuti. Di seguito è riportato l'output dei primi pochi nomi di file: Nome file_2011_01_11_1630.dat Nome file_2011_01_11_1830.dat Nome file_2011_01_11_1900.dat Nome file_2011_01_11_2030.dat Nome file_2011_01_11_2100.dat
Strawberrie

@strawberrie non lo so ... l'ho testato e ha funzionato bene per me senza alcun problema..hai eseguito lo script sostituendolo /path/to/filecon il percorso completo della directory?
heemayl,

2

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

@strawberrie i file rinominati sono ora collocati in una sottocartellarenamed
AB

buona idea per salvare i file rinominati in una cartella aggiuntiva. Nel caso in cui qualcosa vada storto, OP ha ancora originali. Buona idea, quindi +1
Sergiy Kolodyazhnyy,

Grazie @AB Ho ricevuto il seguente errore dopo aver eseguito il tuo script: TimeChange.sh: 21: TimeChange.sh: sostituzione errata Il mio nome file attuale o il prefisso fisso prima che il timestamp sia come FileName_123.Data_YYYY_MM_DD_HHMM.dat
strawberrie

Per definizione, per FileName_123.Data_YYYY_MM_DD_HHMM.datla parte .Data_YYYY_MM_DD_HHMM.datè l'estensione. E quindi FileName_123non è un timestamp valido.
AB,

@strawberrie Ho cambiato il mio copione
AB

1

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.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 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-conversionperché 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 .datfile, 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 *.txtfile per il test, quindi lavoriamo solo con 8 .datfile. Nella directory in cui vanno i file aggiornati, vediamo 8 file, tutti .date 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


a proposito, ls | wc -l prima fornisce 36 file e dopo lo script anche 36 file, nessuno mancante
Sergiy Kolodyazhnyy

Inoltre, il motivo per cui utilizzo il file stat -c% n è perché l'analisi dell'output di ls non è una buona idea, in generale. Alcune persone usano il findcomando, il che è anche buono.
Sergiy Kolodyazhnyy,

Grazie @Serg. Non so perché ho lasciato solo 2 dei 727 file rimasti nella cartella dopo aver eseguito lo script ...
Strawberrie,

C'è stata qualche differenza tra i nomi dei file effettivi e l'esempio che hai pubblicato?
Sergiy Kolodyazhnyy,

inoltre, hai eseguito la prima riga dello "Script in azione"? il rm * era per ripulire la mia directory e quindi creare un mucchio di file di test con date diverse nei nomi dei file. Non
avresti

-1

È possibile utilizzare questo codice per fare ciò che è necessario assumere

  1. dovresti fare il backup e testare prima il codice per vedere se è adatto al tuo caso
  2. stai utilizzando il formato 24H
  3. nessun file verrà nominato dopo le 23:29 (se si dispone di file dopo tale orario, è necessario modificare il codice per modificare anche la data)

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, MMquindi se è inferiore a 30 ne aggiungerà 30 MMse è uguale a 30 o più aggiungerà 1 ora alla HHparte nel nome e detrarrà 30 minuti dal MMparte del nome


per i votanti, si prega di comunicare il motivo?
Fat Mind,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.