Нужна помощь Удаление записей из большого текстового файла на основе содержимого другого текстового файла - PullRequest
1 голос
/ 18 октября 2011

Добрый день. Я мог бы действительно использовать вашу помощь в этом. У меня есть текстовый файл статистики в следующем формате.

ID=1000000 
Name=Name1
Field1=Value1 
...(Fields 2 to 25)
Field26=Value26 

ID=1000001
Name=Name2
Field1=Value1 
...(Fields 2 to 25) 
Field26=Value26

ID=1000002
Name=Name2
Field1=Value1 
...(Fields 2 to 25) 
Field26=Value26 

...goes up to 15000

У меня есть активный текстовый файл людей, разделенный переносами строк.

Name2
Name5
Name11
Name12 
...goes up to 1400 Random Names

Мне нужно иметь возможность удалять записи из текстового файла статистики (ID, имя, поля от 1 до 26), если имя не найдено в активном текстовом файле людей. В приведенном выше примере соответствующая запись для Name1 (ID, Name, Fields1 to 26) должна быть удалена, поскольку ее нет в текстовом файле активных пользователей.

Я попытался переформатировать файл статистики через notepad ++, используя TextFX-> Quick-> Find / Replace, чтобы преобразовать его в разделенный запятыми файл, в котором каждая запись отделяется разрывом строки. Я переставил его на

ID       Name    Field1  ...Fields2 to Fields 25... Field26
1000000  Name1   Value1  ...Value2 to Value 25...   Value26
1000001  Name2   Value1  ...Value2 to Value 25...   Value26
1000002  Name2   Value1  ...Value2 to Value 25...   Value26

Я открыл его с помощью Excel и создал две таблицы (таблица статистики и таблица активных имен) в mysql, используя файл csv. Я не уверен, как обработать это в автоматической функции. Помимо удаления неактивных записей, другая проблема, с которой я столкнулся, - переписать ее обратно в старый формат.

Я изо всех сил пытался понять это часами подряд. Есть ли решение, которое не потребует от меня использования поиска, копирования, вставки и переключения между двумя файлами 1400 раз? К сожалению, мне нужно сохранить файл статистики в этом формате.

Пожалуйста, помогите. Спасибо.

1 Ответ

1 голос
/ 18 октября 2011

Вот программа на C ++, которая обработает файлы для вас:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <locale>
#include <set>
#include <string>
#include <vector>

//trim functions taken:
///203635/kakoi-luchshii-sposob-obrezat-std-string#203656
//with a slight change because of trouble with ambiguity
static int myIsSpace(int test)
{
    static std::locale loc;
    return std::isspace(test,loc);
}
static std::string &rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(myIsSpace))).base(), s.end());
    return s;
}

static std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(myIsSpace))));
    return s;
}

static std::string &trim(std::string &s) {return ltrim(rtrim(s));}

int main(int argc,char * argv[])
{
    std::ifstream peopleFile;
    peopleFile.open("people.txt");

    if (!peopleFile.is_open()) {
        std::cout << "Could not open people.txt" << std::endl;
        return -1;
    }

    std::set<std::string> people;

    while (!peopleFile.eof()) {
        std::string somePerson;
        std::getline(peopleFile,somePerson);
        trim(somePerson);
        if (!somePerson.empty()) {
            people.insert(somePerson);
        }
    }

    peopleFile.close();

    std::ifstream statsFile;
    statsFile.open("stats.txt");

    if (!statsFile.is_open()) {
        std::cout << "could not open stats.txt" << std::endl;
        return -2;
    }

    std::ofstream newStats;
    newStats.open("new_stats.txt");

    if (!newStats.is_open()) {
        std::cout << "could not open new_stats.txt" << std::endl;
        statsFile.close();
        return -3;
    }

    size_t totalRecords=0;
    size_t includedRecords=0;

    bool firstRecord=true;
    bool included=false;
    std::vector<std::string> record;
    while (!statsFile.eof()) {
        std::string recordLine;
        getline(statsFile,recordLine);
        std::string trimmedRecordLine(recordLine);
        trim(trimmedRecordLine);

        if (trimmedRecordLine.empty()) {
            if (!record.empty()) {
                ++totalRecords;

                if (included) {
                    ++includedRecords;

                    if (firstRecord) {
                        firstRecord=false;
                    } else {
                        newStats << std::endl;
                    }

                    for (std::vector<std::string>::iterator i=record.begin();i!=record.end();++i) {
                        newStats << *i << std::endl;
                    }
                    included=false;
                }

                record.clear();
            }
        } else {
            record.push_back(recordLine);
            if (!included) {
                if (0==trimmedRecordLine.compare(0,4,"Name")) {
                    trimmedRecordLine=trimmedRecordLine.substr(4);
                    ltrim(trimmedRecordLine);
                    if (!trimmedRecordLine.empty() && '='==trimmedRecordLine[0]) {
                        trimmedRecordLine=trimmedRecordLine.substr(1);
                        ltrim(trimmedRecordLine);
                        included=people.end()!=people.find(trimmedRecordLine);
                    }
                }
            }
        }
    }

    if (!record.empty()) {
        ++totalRecords;

        if (included) {
            ++includedRecords;

            if (firstRecord) {
                firstRecord=false;
            } else {
                newStats << std::endl;
            }

            for (std::vector<std::string>::iterator i=record.begin();i!=record.end();++i) {
                newStats << *i << std::endl;
            }
            included=false;
        }

        record.clear();
    }

    statsFile.close();
    newStats.close();

    std::cout << "Wrote new_stats.txt with " << includedRecords << " of the " << totalRecords << ((1==totalRecords)?" record":" records") << "found in stats.txt after filtering against the " << people.size() << ((1==people.size())?" person":" people") << " found in people.txt" << std::endl;

    return 0;
}
...