C++ 将相同的 IP 排序在一起,网络日志

C++ sort same IPs together, web log

我需要按 IP 对 Web 日志文件进行排序,因此我需要在下一步下连接相同的 IP。我很懒但是我想学习C++的方法所以我不想在excel中排序。我在日志中做了一些更改,例如在每一行的 IP 是 (8 q [symbols] { qqqqqqqq }) 之后是另一个地址 - 所以我可以按每个字符串的数字对字符串进行排序,因为 IP 没有相同的长度 - 所以我只需要给数组一行 16 个字符并进行比较 - 至少我认为这是个好主意。

日志示例:

85.xx.xx.58 qqqqqqqq    85.xx.xx.58.xxxxxxxxx   bla,bla,bla,bla,
105.216.xx.xx   qqqqqqqq    - bla,bla,bla,bla,bla,bla,bla,
85.xx.xx.58 qqqqqqqq    85.xx.xx.58.xxxxxxxxx   bla,bla,bla,bla,

日志有60000多行,我用C++擦掉了robot.txt、.js、.gif、.jpg等行,所以我有点想回收旧代码。 "robot.txt" 删除行的示例。

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main()
{
ifstream infile("C:\ips.txt");
ofstream myfile;
string line;

while (getline(infile, line)) {

    myfile.open("C:\ipout.txt");

    for (string line; getline(infile, line); ) {
        if (line.find("robots.txt") != string::npos)
                myfile << line << "\n";
    }
}

infile.close();
myfile.close();

cout << " \n";
cin.get();

return 0;
}

我知道这段代码看起来很糟糕,但它确实起作用了,我还在学习,当然我想要旧文件和另一个文件(新文件)。

我找到了关于这个主题的帮助,但对我来说有点偏离方向...

我正在考虑将 "if" 语句更改为只读取 16 个字符,比较它们并将它们连接起来(在彼此下面,连接到行)当然整行应该是完整的 - 如果可能的话。

我不确定我是否真的理解日志格式,但我想您可以调整它以满足您的需要。

这假定基于行的日志格式,其中每一行都以您要分组的键(例如 ip 号)开头。它使用 unordered_map,但您也可以尝试使用普通的 map。映射中的键是 IP 号,该行的其余部分将放入字符串向量中。

#include <iostream>
#include <vector>
#include <sstream>
#include <unordered_map>

// alias for the map
using logmap = std::unordered_map<std::string, std::vector<std::string>>;

logmap readlog(std::istream& is) {
    logmap rv;
    std::string line;
    while(std::getline(is, line)) {
        // put the line in a stringstream to extract ip and the rest
        std::stringstream ss(line);
        std::string ip;
        std::string rest;
        ss >> ip >> std::ws;
        std::getline(ss, rest);
        // add your filtering here 
        // put the entry in the map using ip as key
        rv[ip].push_back(rest);
    }
    return rv;
}

int main() {
    logmap lm = readlog(std::cin);
    for(const auto& m : lm) {
        std::cout << m.first << "\n";
        for(const auto& l : m.second) {
            std::cout << " " << l << "\n";
        }
    }
}

鉴于此输入:

127.0.0.1 first ip first line
192.168.0.1 first line of second ip
127.0.0.1 this is the second for the first ip
192.168.0.1 second line of second ip
127.0.0.1 and here's the third for the first
192.168.0.1 third line of second ip

这是一个可能的输出:

192.168.0.1
 first line of second ip
 second line of second ip
 third line of second ip
127.0.0.1
 first ip first line
 this is the second for the first ip
 and here's the third for the first

感谢 post 和代码,很有帮助,我学到了新东西。你是对的,我对我想要的东西的描述有点奇怪,但我允许自己根据我的需要改变你的代码。因此,对于寻找这种网络日志更改的人,我将分享此代码。

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <unordered_map>

using namespace std;

using logmap = std::unordered_map<std::string, std::vector<std::string>>;

logmap readlog(std::istream& is) {
logmap rv;
std::string line;
while (std::getline(is, line)) {
    // put the line in a stringstream to extract ip and the rest
    std::stringstream ss(line);
    std::string ip;
    std::string rest;
    ss >> ip >> std::ws;
    std::getline(ss, rest);
    // add your filtering here 
    // put the entry in the map using ip as key
    rv[ip].push_back(rest);
}
return rv;
}

int main() {

ifstream infile("C:\ips.txt");
ofstream myfile;
myfile.open("C:\ipout.txt");
long nr = 0;

logmap lm = readlog(infile);
for (const auto& m : lm) {
    nr++;
    for (const auto& l : m.second){
        myfile << nr << " " << m.first << " " << l << "\n";
    }
}
infile.close();
myfile.close();
std::cout << "Enter ! \n";
std::cin.get();

return 0;
}

输入(ips.txt)- 网络日志文件:

1.2.3.4     qqqqqqqq    GET" line code, code,code,code,code,code,code,
5.6.7.8     qqqqqqqq    code,code,code,code,code,code,code,code,tygy
9.10.11.12  qqqqqqqq    all
1.2.3.4     qqqqqqqq    GET" line code, code,code,code,code,code,code,6fg
3.6.7.2     qqqqqqqq    GET" line code,
5.6.7.8     qqqqqqqq    code,code,code,code,code,code,code,code,s5
1.2.3.4     qqqqqqqq    GET" line code, code,code,code,code,code,code,
9.10.11.12  qqqqqqqq    all

代码输出(ipout.txt):

1 5.6.7.8 qqqqqqqq  code,code,code,code,code,code,code,code,tygy
1 5.6.7.8 qqqqqqqq  code,code,code,code,code,code,code,code,s5
2 1.2.3.4 qqqqqqqq  GET" line code, code,code,code,code,code,code,
2 1.2.3.4 qqqqqqqq  GET" line code, code,code,code,code,code,code,6fg
2 1.2.3.4 qqqqqqqq  GET" line code, code,code,code,code,code,code,
3 9.10.11.12 qqqqqqqq   all
3 9.10.11.12 qqqqqqqq   all
4 3.6.7.2 qqqqqqqq  GET" line code,

还有我第一个问题的代码,可以帮助你删除不需要的行。

所以再次感谢你我的英雄 >> Ted Lyngmo <<,长寿和繁荣:-)。