lazarus(pascal)和c语言读日志文件筛选保存为新文件,源于看日志每次从一个很多内容文件里查找不方便,写个代码输入时分秒参数,然后按行读取比较日志时间,当前秒和上一秒的输出保存为新文件,只保存2秒钟文件小多了,容易观察。
首先上pascal代码
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes,
SysUtils,
CustApp,
dateutils { you can add units after this };
type
{ analyselog }
analyselog = class(TCustomApplication)
protected
procedure DoRun; override;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure WriteHelp; virtual;
procedure outLog(fn,outf,t, nextt: string); virtual;
function changeSencond(dt: ttime; d: integer): ttime; virtual;
end;
{ analyselog }
procedure analyselog.DoRun;
var
fn: string;
dt1,dt2: string;
dt: TTime;
begin
if GetParamCount > 1 then
begin
dt2:= GetParams(1);
writeln(dt2);
dt := changeSencond(StrToTime(dt2), -1);
dt1 := timetostr(dt);
writeln(dt1);
fn := format('%s/dms-jc5000.txt', [GetParams(2)]);
writeln(GetParams(2));
writeln(fn);
if FileExists(fn) then outLog(fn,'jc5000.txt',dt1, dt2);
if GetParamCount > 2 then
begin
fn := format('%s/dms-all.txt', [GetParams(2)]);
if FileExists(fn) then outLog(fn,'dmsall.txt',dt1, dt2);
end
end
else
WriteHelp;
Terminate;
end;
constructor analyselog.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
StopOnException := True;
end;
destructor analyselog.Destroy;
begin
inherited Destroy;
end;
procedure analyselog.WriteHelp;
begin
{ add your help code here }
writeln('normal usage example: ', ExeName, ' 06:39:37 /root/logs ');
writeln('then we will get /root/logs/jc5000.txt from 06:39:36 to 06:39:37');
writeln('other usage example: ', ExeName, ' 06:39:37 /root/logs all');
writeln('then we will get /root/logs/jc5000.txt and /root/logs/dmsall.txt from 06:39:36 to 06:39:37');
end;
function analyselog.changeSencond(dt: ttime; d: integer): ttime;
var
Hour, Min, Sec, MSec: word;
begin
DecodeTime(dt, Hour, Min, Sec, MSec);
Sec := Sec + d;
Result := EncodeTime(Hour, Min, Sec, MSec);
end;
procedure analyselog.outLog(fn,outf,t, nextt: string);
var
F: TextFile;
oL: TStringList;
d, linestr: string;
tover: integer;
begin
AssignFile(F, fn);
Reset(F);
tover := 0;
oL := TStringList.Create;
while not EOF(F) do
begin
ReadLn(F, linestr);
if length(linestr) > 0 then
begin
d := copy(linestr, 1, 8);
if (0 = comparetext(d, t)) or (0 = comparetext(d, nextt)) then
begin
writeln(linestr);
oL.Add(linestr);
tover := 1;
end
else
begin
if tover > 0 then break;
end;
end;
end;
CloseFile(F);
oL.SaveToFile(outf);
oL.Free;
end;
var
Application: analyselog;
{$R *.res}
begin
Application := analyselog.Create(nil);
Application.Title := 'analyse';
Application.Run;
Application.Free;
end.
实现过程中发现pascal里没有直接命令复制文件,只好外面整个脚本,因为我这从文件里查找内容不能影响原先文件被别的应用继续写
#!/bin/bash
if [ ! -n "$1" ] ;then
echo "you have not input a hh:mm:ss !"
echo "example : ./getjc5000log.sh 06:39:37"
else
echo "the word you input is $1"
d='/root/logs'
cp -f $d/dms-jc5000.log $d/dms-jc5000.txt
cp -f $d/dms-all.log $d/dms-all.txt
./analyselog $1 ${d} all
fi
写完之后运行可以,但是觉得发布试用要2个文件稍微不完美,好吧,再用c实现一下
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#define _XOPEN_SOURCE
#define __USE_XOPEN
#include <time.h>
// 每行最大长度
#define LINE_MAX 2048
//判断一行数据是否有可打印的字符,只有空格不可见的不算,然后判断行首是否满足需要
int isblankline(char str[], char* time1, char* time2) {
int k = 0;
for (int i = 0; str[i] != '\0'; i++) {
if (0 == isgraph(str[i])) {
k = 1;
break;
}
}
if (1 == k && (0 == strncmp(str, time1, 8) || 0 == strncmp(str, time2, 8))) {
return 1;
}
return 0;
}
//将字符串转成时间戳,偏移后输出字符串
long analyse_time(char* str_time, char* new_time)
{
struct tm stm;
memset(&stm, 0, sizeof(stm));
strptime(str_time, "%H:%M:%S", &stm);
stm.tm_year = 70;
stm.tm_mday = 1;
stm.tm_mon = 1;
printf("str_time= %d %d %d %d\n", stm.tm_hour, stm.tm_min, stm.tm_sec, sizeof(new_time));
stm.tm_sec--;
long t = mktime(&stm);
struct tm tm2 = *localtime(&t);
strftime(new_time, 10, "%H:%M:%S", &tm2);
printf("new_time= %s sec %d\n", new_time, tm2.tm_sec);
return 0;
}
// 按行读文件满足需要的另存为文件
int createfile(char* file1, char* file2, char* file3, char* time1, char* time2) {
char cmd[128] = { 0 };
sprintf(cmd, "cp -f %s %s", file1, file2);
int k = system(cmd);
printf("cp %s !%d\n", file2, k);
if (access(file2, F_OK) == 0) {
FILE* fp = fopen(file2, "r");
FILE* out = fopen(file3, "w");
if (NULL == fp) {
printf("open file failed.\n");
return -1;
}
if (NULL == out) {
printf("out file failed.\n");
return -1;
}
int line_len = 0; // 文件每行的长度
char buf[LINE_MAX] = { 0 }; // 行数据缓存
while (fgets(buf, LINE_MAX, fp)) {
line_len = strlen(buf);
if (isblankline(buf, time1, time2)) {
printf("%s\n", buf);
/** 对每行数据(buf)进行处理 **/
fputs(buf, out);
}
}
if (0 == feof) {
// 未读到文件末尾
printf("fgets error no end\n");
}
fclose(fp);
fclose(out);
}
else {
printf("isnotexist %s!\n", file2);
}
}
int main(int argc, char* argv[])
{
char newtime[10] = { 0 };
printf("hello world\n Harmony is coming!%d\n", argc);
if (argc < 2) {
printf("no param ! example: ./loganalyse 00:00:11\n");
return 1;
}
else {
printf("app= %s param = %s\n", argv[0], argv[1]);
analyse_time(argv[1], newtime);
}
createfile("dms-all.log", "dms-all.txt", "dmsall.txt", newtime, argv[1]);
createfile("dms-jc5000.log", "dms-jc5000.txt", "jc5000.txt", newtime, argv[1]);
return 0;
}