Unix - 从第一列中包含日期超过7天的文件中删除行

时间:2016-04-19 20:15:25

标签: date unix awk unix-timestamp

我生成了当前日志文件来监视文件空间。但是,我想删除文件中超过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 date的文件,但没有任何文件可以满足基于相同文件删除文件中的行的要求。

我确实找到了几个想法: 如果您计算在致电之前应忽略这些行的日期 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

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

2 个答案:

答案 0 :(得分:0)

如果所有其他方法都失败了,请使用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; });
    }
}

答案 1 :(得分:0)

首先,以您的格式制作一个阈值:

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

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

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

>的效率略高于>=,所以:

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