Nieuws:

We zijn er weer.

Na lange tijd van afwezigheid zijn we er weer  :laugh:
We hebben alle wachtwoorden gereset, je oude wachtwoord werkt niet meer.Je moet via het "wachtwoord vergeten"-linkje je wachtwoord resetten. Je krijgt hiervoor een mailtje op het adres dat je bij ons geregistreerd hebt.

De komende tijd zijn we nog druk bezig om de rest van de site op te bouwen, dus het kan zijn dat sommige onderdelen (tijdelijk) niet werken.

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Dubbele namen filteren uit txt file (c++ of bash)  (gelezen 2016 keer)

Offline yozdje

  • Lid
  • Steunpunt: Nee
Dubbele namen filteren uit txt file (c++ of bash)
« Gepost op: 2009/12/02, 23:12:00 »
Stel ik heb een txt-file met daarin onder elkaar allemaal regels info over een bepaalde persoon. Zoiets:

lidnummer, naam, adres, X
lidnummer, naam, aders, X

etc.

Nu is het zo dat sommige personen 2 keer (of nog vaker) in de lijst voorkomen (niet direct onder elkaar, maar door de hele lijst heen). Het lidnummer is dan wel gelijk, maar het adres is anders. Ik wil nu een 2e txt-file maken met daarin al die dubbele gegevens.

Ik ben op de hoogte van de volgende commando's:

sort file.txt | uniq > file2.txt

Dan krijg ik een textfile met daarin alle unieke personen. Ik wil echter een txt-file met al die dubbele. Kan dit ook zo simpel? En hoe kan dit in C++? (liever in c++ aangezien ik het programma eigenlijk ook op een windows machine wil kunnen uitvoeren)

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: Dubbele namen filteren uit txt file (c++ of bash)
« Reactie #1 Gepost op: 2009/12/03, 03:10:41 »
uniq -d in plaats van uniq zal enkel de duplicaten tonen,
maar als een duplicaat volgens jouw definitie ook een duplicaat is wanneer het lidnummer dubbel is, maar niet noodzakelijk de hele lijn, dan moet je het anders doen, bijvoorbeeld zo:
awk '{print $1}' test.in | sort | uniq -d
zo krijg je de lidnummers te zien die dubbel zijn

een iets geavanceerder voorbeeldje:
sort test.in | awk '{print $2, $3, $4, $1}' | uniq -D -f3 | awk '{print $4, $1, $2, $3}'

de lijst wordt gesorteerd op lidnummer, awk zal het lidnummer daarna achteraan zetten zodat aan uniq de parameter -f3 kan meegegeven worden om aan te tonen dat de eerste 3 velden niet gecontroleerd moeten worden (uniq heeft namelijk geen optie om enkel het eerste veld te controleren, wel de eerste X karakters, maar dat is in dit geval niet bruikbaar), -D print alle duplicaten uit inclusief alle informatie, en het laatste awk commando herstelt de oorspronkelijke syntax
« Laatst bewerkt op: 2009/12/03, 04:15:54 door profoX »
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: Dubbele namen filteren uit txt file (c++ of bash)
« Reactie #2 Gepost op: 2009/12/03, 03:53:23 »
Dit is een voorbeeldje van hoe je hetzelfde kan simuleren in standaard C++/STL

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

string getnumpart(string s)
{
    int i = s.find(',');
    return s.substr(0, i);
}

int main(int argc, char **argv)
{
    // check parameter
    if (argc < 2) {
        cout << "Gebruik: " << argv[0] << " <inputbestand>" << endl;
        return 1;
    }

    // open file
    ifstream file;
    file.open(argv[1], ifstream::in);
    if (file.is_open()) {
        vector<string> list;
        vector<string>::iterator it;
        string s;

        // read file contents in list
        while (file.good()) {
            getline(file, s);
            if (s.size() > 0)
                list.push_back(s);
        }
        // sort list using default sort algo
        sort(list.begin(), list.end());

        // iterate over sorted list and find double numbers
        string s_prev, s_now;
        bool print_old = true;
        for (unsigned int i = 1; i < list.size(); ++i) {
            s_prev = getnumpart(list[i-1]);
            s_now = getnumpart(list[i]);
            if (s_now == s_prev) {
                if (print_old) {
                    cout << list[i-1] << endl;
                    print_old = false;
                }
                cout << list[i] << endl;
            } else
                print_old = true;
        }
    } else {
        cout << "Kon '" << argv[1] << "' niet openen" << endl;
        return 1;
    }
    file.close();

    return 0;
}
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: Dubbele namen filteren uit txt file (c++ of bash)
« Reactie #3 Gepost op: 2009/12/04, 03:38:35 »
Laat me maar iets weten indien je toevallig iets anders bedoelde...
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline track

  • Lid
  • Steunpunt: Nee
Re: Dubbele namen filteren uit txt file (c++ of bash)
« Reactie #4 Gepost op: 2009/12/04, 15:08:56 »
Hoi yozdje,

wat jij zoekt is eigenlijk een typische taak voor  awk !  ( http://linux.die.net/man/1/awk )
Een handleiding erbij:  http://www.ibm.com/developerworks/library/l-awk1.html

Zit er altijd een komma tussen het lidnummer en de rest ?

Dan wordt het dit:
sort file.txt | awk -f  ledenfilter.awkmet het awk-scriptje  "ledenfilter.awk" als volgt:
BEGIN {
system("mv -f dubbele.txt dubbele~.txt");
FS= ","; # komma als Field Seperator instellen
}
#------------------------------------------------------------------------------
  {
lidnummer= $1 ;

if(vorige_nummer == lidnummer) {
if(tweede_regel == 0) {
print vorige_regel >> "dubbele.txt";
}
print $0 >> "dubbele.txt";
tweede_regel= 1 ;
}
else tweede_regel= 0 ;

vorige_regel= $0 ; # sla de vorige regel op
vorige_nummer= lidnummer ;
}
en het resultaat in "dubbele.txt" .

track
« Laatst bewerkt op: 2009/12/04, 15:11:30 door track »

Offline yozdje

  • Lid
  • Steunpunt: Nee
Re: Dubbele namen filteren uit txt file (c++ of bash)
« Reactie #5 Gepost op: 2009/12/04, 23:55:44 »
Bedankt voor de replies! Ik ga er even mee aan de slag. Kom er nog op terug!