如何更改文件名时间戳?


8

我按时间顺序排列了dat文件的名称:

FileName_YYYY_MM_DD_HHMM.dat

是否有任何命令可将每个时间戳增加30分钟?


1
那些时间戳与其创建日期相同吗?和ls --full-time吗?
Sergiy Kolodyazhnyy,2015年

1
不可以,时间戳记与它们的创建/修改日期不同。时间戳基于测量数据的时间。
strawberrie

1
看到,由于这些时间戳是自定义的,因此将需要一个脚本,该脚本必须计算出将日期增加30分钟,因此不会有任何简单的命令。所以人们可能需要一点回应
Sergiy Kolodyazhnyy 2015年

1
是否有接近午夜的时间戳记,以至于增加30分钟可能需要将一天更改一整天?
Sergiy Kolodyazhnyy

1
小时是什么格式?12,然后是1,2,3(12小时制)或12至13至14、15。。。23,00(24小时制)?
Sergiy Kolodyazhnyy,2015年

Answers:


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分钟),重命名的文件将覆盖下一个文件,因此最好将秒数添加到重命名的文件名中,以便保持安全。否则,您需要将重命名的文件保存到其他目录,然后在以后用原始文件替换它们。


您和python,真挚的爱。=)+1
AB

您不应Filename_在重命名方法中使用该字符串。
AB

@AB为什么?(也为您+1)
heemayl 2015年

您知道为什么在运行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

@strawberrie重命名的文件现在放在子文件夹中renamed
AB

将重命名的文件保存到其他文件夹中的好主意。万一出了问题,OP仍保留原件。好思想,因此+1
Sergiy Kolodyazhnyy

由于@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不是有效的时间戳。
2015年

@strawberrie我更改了脚本
AB

1

脚本

这是我原始脚本的编辑版本。OP最初并未提供有关命名格式的完整信息。该脚本适用于注释中提到的OP是正确的文件命名。

*技术说明:*

在此脚本中,我们使用awk将文件名分为6个单独的字段,并使用下划线作为字段分隔符。前两个字段$ 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部分为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系统将时间计算为Epoch时间,或者简单地说是秒。

*)脚本获取每个文件名,提取日期,将其转换为纪元,增加1800秒(恰好是30分钟),并使用新的时间戳保存文件。

*)该脚本解决了OP的要求-更改文件名中的时间戳,而不更新文件本身的创建时间

使用的工具:

  • Ubuntu的04.04

  • GNU bash 4.3.30

  • GNU awk 4.1.1

  • 日期(GNU coreutils)8.23


顺便说一句,ls | wc -l之前提供了36个文件,脚本之后也提供了36个文件,均不丢失
Sergiy Kolodyazhnyy 2015年

另外,我之所以使用stat -c%n文件,是因为解析ls的输出通常不是一个好主意。有些人使用find命令,这也很好。
Sergiy Kolodyazhnyy,2015年

谢谢@Serg。我不知道为什么,我只运行脚本后留下2出左侧的文件夹中的文件727 ...
strawberrie

实际文件名和您发布的示例之间是否有区别?
Sergiy Kolodyazhnyy

另外,您是否在“运行中的脚本”中运行了第一行?rm *用于清理我自己的目录,然后创建一堆文件名称不同日期的测试文件。您不应该这样做
Sergiy Kolodyazhnyy 2015年

-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,则会将HH名称中的分钟加1小时,并从档案中 扣除30分钟MM名称的一部分


对于不赞成投票的人,请告知原因?
Fat Mind
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.