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

8

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

FileName_YYYY_MM_DD_HHMM.dat

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

strawberrie
источник
1
эти метки времени совпадают с датой их создания? это так же, как ls --full-time?
Сергей Колодяжный
1
Нет, отметки времени отличаются в зависимости от даты их создания / изменения. Метки времени основаны на времени, когда были измерены данные.
strawberrie
1
Видите ли, поскольку эти временные метки являются собственными, для этого потребуется скрипт, который должен рассчитывать добавление 30 минут к дате, простой команды не будет. так что людям может потребоваться немного времени, чтобы ответить
Сергей Колодяжный
1
есть ли метки времени, которые близки к полуночи, так что добавление 30 минут может привести к необходимости смены дня на один?
Сергей Колодяжный
1
в каком формате часы? 12, затем 1,2,3 (12-часовой формат) или от 12 до 13 до 14, 15. , , 23, 00 (24-часовой формат)?
Сергей Колодяжный

Ответы:

6

Использование 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 минут) переименованный файл будет перезаписывать следующий, поэтому лучше добавить секунды к переименованному имени файла, чтобы он оставался безопасным. В противном случае вам нужно сохранить переименованные файлы в другой каталог, а затем заменить их исходными.

heemayl
источник
Ты и питон, великая любовь. =) +1
АВ
Вы не должны использовать строку Filename_в методе переименования.
АВ
@AB Почему это? (+1 для вас тоже)
Heemayl
Знаете ли вы, почему у меня пропали некоторые файлы после запуска скрипта Python? Временная метка для каждого файла имеет 30-минутную разницу. Ниже приведены выходные данные для первых нескольких имен файлов: 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 Я не знаю .. Он проверил это и работает хорошо для меня без каких-либо проблем .. Вы запустили скрипт, заменив /path/to/fileполный путь к каталогу?
Heemayl
2

Используя bash, переименованные файлы находятся в новой подпапке 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
AB
источник
@strawberrie переименованные файлы теперь помещаются в подпапкуrenamed
AB
хорошая идея сохранить переименованные файлы в дополнительную папку. На случай, если что-то пойдет не так, у OP останутся оригиналы. Хорошее мышление, отсюда +1
Сергей Колодяжный
Спасибо @AB Я получил следующую ошибку после запуска вашего скрипта: TimeChange.sh: 21: TimeChange.sh: неправильная подстановка Мое фактическое имя файла или фиксированный префикс перед отметкой времени похож на FileName_123.Data_YYYY_MM_DD_HHMM.dat
strawberrie
По определению, для FileName_123.Data_YYYY_MM_DD_HHMM.datчасти .Data_YYYY_MM_DD_HHMM.datэто расширение. И, следовательно FileName_123, не является действительной отметкой времени.
АВ
@strawberrie У меня изменился сценарий
AB
1

SCRIPT

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

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

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

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

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

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

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat копирует старый файл в каталог "convert_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потому, что я разработал сценарий из заметок, которые я сделал, работая над этим вопросом.

Обратите внимание, что имена файлов, которые имеют часть ЧЧММ как 2345 (то есть за 15 минут до полуночи), обновляются до 0015, а часть DD обновляется до следующего дня. 24-часовой формат сохранен.

Кроме того, поскольку цикл for ищет только .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 $ 

ОБЪЯСНЕНИЕ (из оригинального поста)

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

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

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

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

  • Ubuntu 15.04

  • GNU bash 4.3.30

  • GNU awk 4.1.1

  • дата (GNU coreutils) 8,23

Сергей Колодяжный
источник
кстати, ls | wc -l до дает 36 файлов, а после скрипта также 36 файлов, ни один не пропал
Сергей Колодяжный
Кроме того, причина, по которой я использую файл stat -c% n, заключается в том, что синтаксический анализ вывода ls не является хорошей идеей. Некоторые люди используют findкоманду, что тоже хорошо.
Сергей Колодяжный
Спасибо @Serg. Я не знаю, почему я оставил только 2 из 727 файлов, оставленных в папке после запуска вашего скрипта ...
strawberrie
Была ли какая-то разница между реальными именами файлов и примером, который вы разместили?
Сергей Колодяжный
Кроме того, вы запустили первую строку в «Сценарий в действии»? rm * предназначался для очистки моего собственного каталога, а затем для создания набора тестовых файлов с разными датами в именах файлов. Вы не должны были это запускать
Сергей Колодяжный
-1

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

  1. Вы должны сначала сделать резервную копию и протестировать код, чтобы увидеть, подходит ли он для вашего случая
  2. вы используете формат 24H
  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часть имени

Жирный разум
источник
для избирателя вниз, пожалуйста, сообщите причину?
Fat Mind