我有一个 bash 脚本,生成以下格式的 csv 文件:
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
...
056_log_YYYYmmddHHMM.csv
067_dat_YYYYmmddHHMM.csv
其中YYYYmmddHHMM
是 csv 文件本身包含的数据的时间戳,而不是 csv 文件的创建时间。
所以我想编写一个bash脚本来比较当前系统时间(格式与csv文件相同,即YYYYmmddHHMM
)与文件名上的时间戳,
如果两者之间的差异大于或等于 120 分钟,则必须将文件移至old_data
目录。
如果两者之间的差异小于 120 分钟,则必须将文件移动到current_data
目录
使用当前系统时间 202312291048,必须按如下方式移动文件:
~/old_data/
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
~/current_data/
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
到目前为止,我知道我可以使用我想要的格式获取当前时间:
CUR_TIME="`date +%Y%m%d%H%M`";
并使用以下命令从 csv 文件获取时间戳:
ls 056*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 056 files
ls 067*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 067 files
从那时起,我不知道如何继续前进..请帮助。
这就是我能想到的:
#!/bin/bash
CUR_TIME=$(date +%Y%m%d%H%M);
for csvfile in *.csv
do
TIME_DIFF=0
TIMESTAMP= $(echo $csvfile | cut -d'_' -f 3 | cut -c -12)
TIME_DIFF= $CUR_TIME-$TIMESTAMP
if $TIME_DIFF >= 120
then
mv -f $csvfile ~/old_data/
else
mv -f $csvfile ~/current_data/
fi
done
您不能简单地减去这样的日期戳,因为例如,202312291607(即2023/12/29 16:07)减去60是202312291547,实际上是2023/12/29 15:47,所以不是60分钟前,而是20分钟前。请记住,我们使用以 60 为基数的系统来测量时间,因此我们不能像您建议的那样进行简单的以 10 为基数的计算。常见的解决方案是将时间转换为自 epoch 以来的秒数,然后比较它们以获得以秒为单位的差异,然后将其转换为分钟。例如:
运行上面的脚本,如果它看起来像您想要的那样工作,请删除
echo
以实际运行mv
命令并移动文件。这里的技巧是使用基本的字符串操作从文件名中提取时间戳。该语法将从字符串开头
${var##pattern}
删除最长的匹配项。pattern
在这里,模式是*_
,所以一切直到 _。她正在行动:因此
${csvfile##*_}
删除直到最后的所有内容_
,留下 datestamp plus.csv
。该basename
命令旨在删除文件名中的路径并仅保留文件名,但它还有一个删除提供的扩展名的有用技巧,因此这就是我使用basename
with.csv
来获取实际时间戳的原因:其余部分相对简单。简单
if
检查时差是否超过120分钟。请注意,由于我处理的时间以秒为单位,因此我必须除以 60 t 才能得到分钟。或者,我可以将 120 分钟转换为 7200 秒 (120 x 60):重要提示:如果您有很多文件,并且处理可能需要几分钟甚至几小时,请注意,每个文件仍将与脚本启动的时间进行比较。这意味着脚本到达时可能早于 120 分钟但脚本启动时并非如此的内容将不会被移动。如果您不想这样做,请将该
curr_time=$(date +%s)
行移到循环内for
,以便为每个文件重置它。