尝试让以下内容发挥作用有点麻烦。
我有一个包含主机名:时间戳
的文件,如下所示:
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/