AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 765763
Accepted
dante_t
dante_t
Asked: 2023-12-29 18:06:57 +0800 CST2023-12-29 18:06:57 +0800 CST 2023-12-29 18:06:57 +0800 CST

根据文件名上的时间戳将文件移动到特定目录

  • 772

我有一个 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
shell-script
  • 1 1 个回答
  • 49 Views

1 个回答

  • Voted
  1. Best Answer
    terdon
    2023-12-29T22:25:20+08:002023-12-29T22:25:20+08:00

    您不能简单地减去这样的日期戳,因为例如,202312291607(即2023/12/29 16:07)减去60是202312291547,实际上是2023/12/29 15:47,所以不是60分钟前,而是20分钟前。请记住,我们使用以 60 为基数的系统来测量时间,因此我们不能像您建议的那样进行简单的以 10 为基数的计算。常见的解决方案是将时间转换为自 epoch 以来的秒数,然后比较它们以获得以秒为单位的差异,然后将其转换为分钟。例如:

    #!/bin/bash
    
    ## Get the current time in seconds since the epoch
    curr_time=$(date +%s)
    
    for csvfile in  *.csv; do
      ## Extract the timestamp from the csv file name. 
      csv_date_string=$(basename "${csvfile##*_}" .csv |
                          sed -E 's|(....)(..)(..)(..)(..)|\1/\2/\3 \4:\5|')
      ## Convert the csv datestamp to seconds since the epoch 
      csv_time=$( date -d "$csv_date_string" +%s)
    
      ## Compare to the current time and, if more than or equal to 120
      ## echo the mv command, if less, echo that we do nothing.
      if [[ $(( (curr_time - csv_time) / 60)) -ge 120 ]]; then
        echo mv "$csvfile" old_data
      else
        echo "Not moving $csvfile"
      fi
      
    done
    

    运行上面的脚本,如果它看起来像您想要的那样工作,请删除echo以实际运行mv命令并移动文件。

    这里的技巧是使用基本的字符串操作从文件名中提取时间戳。该语法将从字符串开头${var##pattern}删除最长的匹配项。pattern在这里,模式是*_,所以一切直到 _。她正在行动:

    $ csvfile=056_log_202312290736.csv
    $ echo ${csvfile##*_}
    202312290736.csv
    

    因此${csvfile##*_}删除直到最后的所有内容_,留下 datestamp plus .csv。该basename命令旨在删除文件名中的路径并仅保留文件名,但它还有一个删除提供的扩展名的有用技巧,因此这就是我使用basenamewith.csv来获取实际时间戳的原因:

    $ basename "${csvfile##*_}" .csv
    202312290736
    

    其余部分相对简单。简单if检查时差是否超过120分钟。请注意,由于我处理的时间以秒为单位,因此我必须除以 60 t 才能得到分钟。或者,我可以将 120 分钟转换为 7200 秒 (120 x 60):

    if [[ $(( curr_time - csv_time )) -ge 7200 ]]; then
    

    重要提示:如果您有很多文件,并且处理可能需要几分钟甚至几小时,请注意,每个文件仍将与脚本启动的时间进行比较。这意味着脚本到达时可能早于 120 分钟但脚本启动时并非如此的内容将不会被移动。如果您不想这样做,请将该curr_time=$(date +%s)行移到循环内for,以便为每个文件重置它。

    • 1

相关问题

  • 在awk中的两行之间减去相同的列

  • 打印文件行及其长度的脚本[关闭]

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 按分隔符拆分并连接字符串问题

  • MySQL Select with function IN () with bash array

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve