bash - 使用时间戳 bash 删除文件中超过一小时的行

标签 bash sed timestamp

尝试让以下内容发挥作用有点麻烦。

我有一个包含主机名:时间戳的文件,如下所示:

hostname1:1445072150
hostname2:1445076364

我正在尝试创建一个 bash 脚本来查询该文件(使用 cron 作业)来检查时间戳是否超过 1 小时,如果是,则删除该行。 下面是我到目前为止所拥有的内容,但它似乎没有删除文件中的行。

#!/bin/bash

hosts=/tmp/hosts
current_timestamp=$(date +%s)

while read line; do
    hostname=`echo $line | sed -e 's/:.*//g'`
    timestamp=`echo $line | cut -d ":" -f 2`
    diff=$(($current_timestamp-$timestamp))
    if [ $diff -ge 3600 ]; then
            echo "$hostname - Timestamp over an hour old. Deleting line."
            sed -i '/$hostname/d' $hosts
    fi
done <$hosts

我已经成功地让时间戳部分正常工作,以识别超过一个小时的旧主机,但无法从文件中删除时间。

我怀疑这可能是由于 while 循环保持文件打开,但不能 100% 确定如何解决它。还尝试制作文件的副本并进行编辑,但仍然没有任何结果。

或者:如果有更好的方法让它工作并产生相同的结果,我愿意接受建议:)

任何帮助将不胜感激。

干杯

最佳答案

你的脚本中的问题就是这一行:

sed -i '/$hostname/d' $hosts

单引号内的变量不会扩展到其值, 因此该命令尝试按字面意思替换“$hostname”,而不是它的值。如果将单引号替换为双引号, 该变量将扩展为其值,这就是您所需要的:

sed -i "/$hostname/d" $hosts

可以进行改进:

#!/bin/bash

hosts=/tmp/hosts
current_timestamp=$(date +%s)

while read line; do
    set -- ${line/:/ }
    hostname=$1
    timestamp=$2
    ((diff = current_timestamp - timestamp))
    if ((diff >= 3600)); then
        echo "$hostname - Timestamp over an hour old. Deleting line."
        sed -i "/^$hostname:/d" $hosts
    fi
done <$hosts

改进:

  • sed 命令中更严格的模式,使其更加健壮并避免一些潜在的错误
  • 无需任何子 shell 即可提取主机名部分和时间戳部分的更简单方法
  • 通过括在 ((...)) 中实现更简单的算术运算

关于bash - 使用时间戳 bash 删除文件中超过一小时的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33185867/

相关文章:

bash - 使用 Perl 通过 Gmail 发送邮件

macos - 在终端中生成随机文本文件

linux - 在 Linux 中生成目录列表作为网络服务器索引页

regex - 如何让 sed 进行非贪婪匹配?

python - 重置 Pandas 时间戳的时间部分

linux - bash 中的这个 perl one liner 是如何工作的?

linux - 使用 Linux 中特定内容行的名称批量重命名 pdf 文件

bash - 替换除字母以外的所有内容

timestamp - AppleScript:QuickTime 影片录制完成后自动保存

PHP 查找最小数字/日期的快捷方式