アクセスログをタブ区切りにする

Pocket

apache のデフォルト combined のログをデータベースに入れたくなりました
ログ出力を最初からタブ区切りの設定にしておけばよかったんですがね・・・

他の言語で書けば良いところを C で書いてみた

#include        <stdio.h>
#include        <string.h>
#include        <stdlib.h>

#define MAXLEN  8192*2
#define TAB     '\t'

int Line2TSV(char *line, char **output)
{
        char *p = NULL, *o = NULL;
        int dquote = 0; /* ダブルクォート中の場合、立てる */

        o = *output;

        memset(o, '\0', MAXLEN);


        for(p=line; *p != '\0'; p++) {
                switch(*p)
                {
                case '\\':
                        /*
                        **      ダブルクォート中でダブルクォートがエスケープされているパターン
                        */
                        if ( dquote && ( *(p+1) == '"' || *(p+1) == '\\'))
                        {
                                p++;
                                *o = *p;
                                o++;
                        }
                        else
                        {
                                *o = *p;
                                o++;
                        }
                        break;
                case '"':
                        if ( dquote)
                                dquote = 0;
                        else
                                dquote = 1;
                        break;
                case ' ':
                        if ( dquote)
                        {
                                *o = *p;
                                o++;
                        }
                        else
                        {
                                *o = TAB;
                                o++;
                        }

                        break;
                case '\r':
                        break;
                case '\n':
                        *o = '\n';
                        o++;
                        break;
                default:
                        *o = *p;
                        o++;
                }
        }

        return 0;
}

int main(int argc, char *argv[])
{
        FILE *fi = NULL, *fo = NULL;
        char line[MAXLEN];
        char *output;

        output = (char *)malloc(MAXLEN);

        fi = fopen( argv[1], "r");
        if ( fi == NULL)
        {
                fprintf(stderr, "Can not find input file %s\n", argv[1]);
                exit(0);
        }

        switch(argc)
        {
        case 3:
                fo = fopen( argv[2], "w");
                if ( fo == NULL)
                {
                        fprintf(stderr, "Can't open output file %s\n", argv[2]);
                        exit(0);
                }

                while (fgets(line,MAXLEN, fi) != NULL) {
                        Line2TSV(line, &output);
                        fputs(output, fo);
                }

                fclose(fo);
                break;
        case 2:
                while (fgets(line,MAXLEN, fi) != NULL) {
                        Line2TSV(line, &output);
                        fputs(output, stdout);
                }

                break;
        default:
                fprintf(stderr, "log2tsv [input] [output] or log2tsv [input]\n");
                exit(0);
        }

        fclose(fi);
        exit(0);
}

上記のプログラムを log2tsv.c として保存します
そしてコンパイルします

 $ gcc -c log2tsv.c
 $ gcc -o log2tsv log2tsv.o

私はcygwin でコンパイルして、windows で使ってますが。

コメントを残す