2016-04-19 3 views
0

Ich habe die aktuelle Protokolldatei erstellt, um den Dateibereich zu überwachen. Ich möchte jedoch Datensätze in der Datei entfernen, die älter als 7 Tage sind.Unix - Entfernen von Zeilen aus der Datei mit Datum in der ersten Spalte älter als 7 Tage

Beispiel Protokolldatei (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%/

Es gibt eine Menge Hilfe ist da draußen für das Löschen von Dateien, die älter sind als x aktuell sind, aber keine, die die Entfernung von Zeilen innerhalb einer Datei erfüllen, basierend auf das Gleiche.

Ich habe ein paar Ideen, wie finden: Wenn Sie berechnen das Datum, bis zu dem die Linien ignoriert werden sollen, bevor Sie awk anrufen, dann können Sie dies tun:

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

Von 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; 

}

Von 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 

Von Grep/awk greater than date

Aber noch einmal, sind diese im Anschluss nicht die gleiche Datumsformatierung ich verwendet habe, und ich habe Fehler wurde erhalten, wenn diese genannten Skripte auszuführen versuchen.

+0

Alternative Ansatz: Was Ihre Logfiles darüber, dass jeden Tag um Mitternacht gedreht? Eine Datei pro 24h wäre wahrscheinlich viel einfacher zu verwalten. – xbug

+0

Ja, lange Protokolldateien sind ein gelöstes Problem; Ich denke, sollte [logrotate] (http://linux.die.net/man/8/logrotate) betrachten. Auf Ihrem System wird möglicherweise bereits logrotate ausgeführt, und Sie müssen lediglich seine Konfiguration bearbeiten. –

Antwort

0

Wenn alles andere fehlschlägt, verwenden 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

zunächst eine Schwelle in Ihrem Format machen:

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

Wahrscheinlicher ist, Sie mal vom ersten Tag enthalten sein sollen:

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

Und > ist etwas effizienter als >=, so:

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

(Ihre Log Unter der Annahme, verwendet 24-Stunden-Zeit.)

Dann awk verwenden Zeilen, die Sie in eine temporäre Datei speichern möchten.

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

Überprüfen Sie, ob es funktioniert, dann die alte Datei überschreiben:

mv -f filesize.last7days.log filesize.log 
Verwandte Themen