我如何更改文件名时间戳?

我如何更改文件名时间戳?

我有按时间顺序排列的数据文件名称:

FileName_YYYY_MM_DD_HHMM.dat

是否有任何命令可以为每一个时间戳添加 30 分钟?

答案1

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

答案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

答案3

脚本

这是我原始脚本的编辑版本。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 系统以纪元时间,或者简单地说是秒。

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

*) 此脚本解决了 OP 想要的问题 - 更改文件名中的时间戳,而不是更新文件本身的创建时间

使用的工具:

  • Ubuntu 15.04

  • GNU bash 4.3.30

  • GNU awk 4.1.1

  • 日期(GNU coreutils)8.23

答案4

您可以使用此代码来执行您需要的假设

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

相关内容