2016-04-19 5 views
0

У меня есть текущий файл журнала, создаваемый для мониторинга файлового пространства. Однако я хочу удалить записи в файле старше 7 дней.Unix - Удаление строк из файла с датой в первом столбце старше 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%/

Существует много помощи там для удаления файлов, которые старше, чем дата х, но ни одно из них удовлетворяют удаление строк в файле на основе тоже самое.

Я нашел пару идей, как: Если рассчитать дату, до которой строки должны игнорироваться перед вызовом 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

Но, еще раз, это не по тому же форматирование даты я использую, и я получаю сообщение об ошибке при попытке запуска этих упомянутых сценариев.

+0

Альтернативный подход: что о том, ваши логах повернута каждый день в полночь? В любом случае, один файл за 24 часа будет намного легче управлять. – xbug

+0

Да, длинные файлы журналов - проблема решена; Я думаю, следует посмотреть на [logrotate] (http://linux.die.net/man/8/logrotate). Возможно, у вашей системы уже есть logrotate, и вам просто нужно отредактировать ее конфигурацию. –

ответ

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; }); 
    } 
} 
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