【问题标题】:Unix - Removing lines from file that have date in first column older than 7 daysUnix - 从文件中删除第一列中日期超过 7 天的行
【发布时间】:2016-04-22 06:52:38
【问题描述】:

我正在生成当前日志文件来监视文件空间。但是,我想删除文件中超过 7 天的记录。

示例日志文件 (filesize.log)

4/10/2016 0:03:48 Filesystem 6.0G 2.6G 3.1G 47% /
4/11/2016 0:08:59 Filesystem 6.0G 2.6G 3.1G 47% /
4/13/2016 0:06:41 Filesystem 6.0G 2.6G 3.1G 47% /
4/15/2016 0:00:16 Filesystem 6.0G 2.6G 3.1G 47% /
4/16/2016 0:03:46 Filesystem 6.0G 2.6G 3.1G 47% /
4/17/2016 0:07:53 Filesystem 6.0G 2.6G 3.1G 47% /
4/19/2016 0:02:26 Filesystem 6.0G 2.6G 3.1G 47% /

对于删除早于 x 日期的文件有很多帮助,但没有一个可以满足基于相同删除文件中的行。

我确实找到了一些想法,例如: 如果您在致电之前计算应忽略行的日期 awk 那么你可以这样做:

awk -v cmpdate=20130628 '{line=$0; dateval=$8;FS="/"; $0=dateval; thisdate=$3*10000+$1*100+$2; if (thisdate>cmpdate) print line; FS=" ";}' file

来自https://unix.stackexchange.com/questions/81829/delete-lines-in-a-csv-file-older-than-7-days

#!/bin/bash
head -n+2 filesize.log | {
  while read line ; do
    tmstmp=$(echo "$line" | awk '{print $8}');
    echo "TMSTMP: $tmstmp" "TMDELTA: $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) ))" "TMWINDOW: $(( 604800 ))"
    [ $(( $(date -d "now" +%s) - $(date -d "$tmstmp" +%s) )) -lt $(( 604800 )) ] && echo "$line";
  done;

}

来自https://unix.stackexchange.com/questions/81829/delete-lines-in-a-csv-file-older-than-7-days

awk 'NF>3{gsub(/-/,"",$NF);if ($NF>d) next}{print $1}' FS="[|@]" d=$(date +%Y%m%d) file

来自Grep / awk greater than date

但是,再一次,这些没有遵循我一直使用的相同日期格式,并且我在尝试运行这些提到的脚本时遇到了错误。

【问题讨论】:

  • 替代方法:让您的日志文件每天午夜轮换怎么样?无论如何,每 24 小时一个文件可能会更容易管理。
  • 是的,长日志文件是一个已解决的问题;我认为应该看看logrotate。您的系统可能已经运行了 logrotate,您只需编辑其配置即可。

标签: date unix awk unix-timestamp


【解决方案1】:

如果一切都失败了,请使用 C++:

#include <iostream>
#include <string>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <iterator>
#include <fstream>
#include <algorithm>

class line {
    std::string data;
public:
    friend std::ostream &operator<<(std::ostream &os, line const &l) { return os << l.data; }

    friend std::istream &operator>>(std::istream &is, line &l) { return std::getline(is, l.data); }

    bool operator<(time_t target) const {
        std::istringstream buffer(data);
        struct tm t;
        buffer >> std::get_time(&t, "%m/%d/%Y %H:%M:%S");
        return mktime(&t) < target;
    }
};

int main(int argc, char **argv) { 
    std::time_t now = std::time(NULL);
    struct tm tm = *std::localtime(&now);

    // For the moment I've hard-coded the number of days ago for the cut-off.
    // Should probably be configurable.
    tm.tm_mday -= 7;

    std::time_t target = mktime(&tm);

    for (int i = 1; i < argc; i++) {
        std::ifstream in(argv[1]);
        std::ofstream out(std::string(argv[1]) + ".trimmed");

        std::remove_copy_if(std::istream_iterator<line>(in), std::istream_iterator<line>(),
            std::ostream_iterator<line>(std::cout, "\n"),
            [&](line const &l) { return l < target; });
    }
}

【讨论】:

    【解决方案2】:

    首先,在您的格式中设置一个阈值:

    start=`date -d '7 days ago' +'%-m/%-d/%y %-H:%M:%S'`
    

    更有可能的是,您希望包括从第一天开始的任何时间:

    start=`date -d '7 days ago' +'%-m/%-d/%y 0:00:00'`
    

    而且&gt;&gt;= 稍微高效一些,所以:

    start=`date -d '8 days ago' +'%-m/%-d/%y 23:59:59'`
    

    (假设您的日志使用 24 小时制。)

    然后使用awk 将您想要的行保存到临时文件中。

    awk -v start="$start" '$1$2>start' filesize.log > filesize.last7days.log
    

    检查它是否有效,然后覆盖旧文件:

    mv -f filesize.last7days.log filesize.log
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-20
      • 2018-11-01
      • 1970-01-01
      • 2018-01-02
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多