我按时间顺序排列了dat文件的名称:
FileName_YYYY_MM_DD_HHMM.dat
是否有任何命令可将每个时间戳增加30分钟?
我按时间顺序排列了dat文件的名称:
FileName_YYYY_MM_DD_HHMM.dat
是否有任何命令可将每个时间戳增加30分钟?
Answers:
使用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分钟),重命名的文件将覆盖下一个文件,因此最好将秒数添加到重命名的文件名中,以便保持安全。否则,您需要将重命名的文件保存到其他目录,然后在以后用原始文件替换它们。
Filename_
在重命名方法中使用该字符串。
/path/to/file
了目录的完整路径?
使用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
renamed
FileName_123.Data_YYYY_MM_DD_HHMM.dat
该部分.Data_YYYY_MM_DD_HHMM.dat
是扩展名。因此FileName_123
不是有效的时间戳。
脚本
这是我原始脚本的编辑版本。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
find
命令,这也很好。
您可以使用此代码来做您需要做的
代码是:
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
名称的一部分
ls --full-time
吗?