Как я могу изменить временную метку имени файла?

У меня есть имена файлов данных в хронологическом порядке:

FileName_YYYY_MM_DD_HHMM.dat

Есть ли какие-либо команды для добавления 30 минут к каждой отметке времени?

8
задан 17 May 2015 в 02:44

4 ответа

Используя 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') изменит текущий каталог на каталог, содержащий эти .dat файлы. Замена /path/to/dir с фактическим путем.

  • glob.glob('*.dat') найдет файлы, заканчивающиеся в .dat

  • ini_time, переменная будет в первом отключать дату и время от исходного имени файла с помощью re модуль и затем разбираться, какая запись представляет то, что в строке, которая вынута так, чтобы мы могли добавить необходимое время к этому

  • fin_time, будет содержать результирующее время, т.е. ini_time плюс 30 минут

  • os.rename переименует файл соответственно.

Также примечание, что, с последовательными именами файлов (отличался на 30 минут) переименованный файл перезапишет следующий, следовательно это лучше добавить секунды к переименованному имени файла так, чтобы это осталось безопасным. Иначе необходимо сохранить переименованные файлы к различному каталогу и затем заменить их исходными позже.

0
ответ дан 17 May 2015 в 02:44

Используя bash, переименованные файлы находятся в новой sub папке renamed.

Запускают сценарий в папке, где файлы расположены.

#!/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

пример произвел:

% 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
0
ответ дан 17 May 2015 в 02:44

СЦЕНАРИЙ

Это - отредактированная версия моего исходного сценария. OP первоначально не предоставил полную информацию о формате имени. Этот сценарий адаптируется к тому, что OP, упомянутая в комментариях, была корректным именованием файла.

*Технические примечания: *

В этом сценарии мы разделяем имя файла на 6 отдельных полей с помощью awk с подчеркиванием как разделитель полей. Сначала два поля, 1$ и 2$ считают строкой статического текста. Поля 3,4,5, и 6 являются меткой времени, в которой данные OP были выбраны, не дата создания файла в файловой системе.

Переменный COPYDIR содержит название нового каталога, куда файлы с обновленной меткой времени пойдут. Мы создаем тот каталог в текущем рабочем каталоге с mkdir $COPYDIR

Переменные TEXTSTRING и DATESTRING содержат статический текст и метку времени соответственно. В демонстрационном выходном реве я использовал две различных строки, чтобы доказать, что сценарий будет работать, независимо от какого текста первые два поля содержат.

NEWEPOCHTIME является переменным, который содержит расчетную новую метку времени в формате эпохи Unix. NEWDATE является переменным, который содержит преобразованную метку времени с эпохи Unix к YYYY-MM-DD HH:MM формат. NEWAPPEND является фактической меткой времени, которая будет добавлена к файлу в желаемом формате OP YYYY_MM_DD_HHMM.

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat копирует старый файл в "converted_files" каталог (вместо перемещения, для предотвращения потери данных) с обновленной меткой даты.

Заметьте, сценарий будет работать, пока формат имени действительно сопровождается, т.е. все файлы, действительно имеют SomeText_123.Data_YYYY_MM_DD_HHMM.dat формат.

#!/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

СЦЕНАРИЙ В ДЕЙСТВИИ

Демонстрационный рев является прямой копией с моего терминала. Заметьте, что я создал исходные файлы с двумя различными строками в первых двух полях. Таким образом, этот сценарий должен работать независимо от того, что находится в начале имени файла, пока существует действительно только две строки, разделенные подчеркиванием

Сценарий назвали notes-conversion потому что я разработал сценарий из примечаний, я взял при работе над этим вопросом.

Заметьте, что имена файлов, которые имеют часть HHMM как 2 345 (который составляет без 15 минут полночь) обновляются к 0015, и часть DD обновляется к следующему дню. 24-часовой формат сохраняется.

Кроме того, потому что для цикла только ищет .dat файлы, мы стараемся не переименовывать другие файлы или каталоги, которые, может оказаться, находятся в рабочем каталоге, таким образом избежав любой потенциальной потери данных. В реве в качестве примера исходный каталог содержит 11 объектов, 3 из которых *.txt файлы для тестирования, таким образом, мы только работаем с 8 .dat файлы. В каталоге, куда обновленные файлы идут, мы видим 8 файлов, все .dat и никакие другие файлы. Данные безопасны, сценарий делает свое задание.

[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 $ 

ОБЪЯСНЕНИЕ (из исходного сообщения)

*) Сегодня я узнал, что системы Linux Unix считают время во время Эпохи или просто помещают секунды.

*) сценарий берет каждое имя файла, дату извлечений, преобразовывает его в эпоху, добавляют 1 800 секунд (который является точно 30 минутами), и сохранил файл с, чем новая метка времени.

*) Этот сценарий обращается к тому, что OP хотела - метка времени изменения в имени файла, не обновляют время создания самого файла

Инструменты использовали:

  • человечность 15.04

  • Удар GNU 4.3.30

  • GNU awk 4.1.1

  • дата (GNU coreutils) 8.23

1
ответ дан 17 May 2015 в 02:44

Можно использовать этот код, чтобы сделать то, что Вам нужно принятие

  1. , необходимо взять резервное копирование и протестировать код сначала, чтобы видеть, подходит ли это для случая
  2. , Вы используете 24-й формат
  3. , которым никакие файлы не назовут после 23:29 (если у Вас есть файлы после того времени, код должен быть изменен для изменения даты также)

, код:

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 ;

, Как это работает: код проверит мелкую часть в имя файла MM тогда, если это будут меньше чем 30, то это добавит 30 к MM, если это будет равняться 30 или больше, то это добавит 1 час к HH часть на имя и вычтет 30 минут от MM часть имени

0
ответ дан 17 May 2015 в 02:44

Другие вопросы по тегам:

Похожие вопросы: