Dateien vergleichen

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von drm, 12.03.2007.

  1. drm

    drm Eroberer

    Dabei seit:
    29.08.2006
    Beiträge:
    59
    Zustimmungen:
    0
    Hallo Ihr,
    ich möchte ein Problem lösen und vielleicht kann mir jemand mit einer guten Idee weiterhelfen. Problemstellung:
    Ich habe eine Datei in der ca. 500 eindeutige Nachnamen drin stehen. Dann habe ich ein Verzeichnis in dem - jedenfalls sollte es so sein - zu jedem der 500 Nachnamen ein Steckbrief als Datei existiert. Ich möchte jetzt die eine Datei mit den 500 eindeutigen Nachnamen mit den 500 Dateien (Steckbriefen) vergleichen und herausfinden ob evtl. irgendwo was fehlt.

    Mein Ansatz:
    Ich müsste jede Datei auslesen, allerdings nur den Nachnamen, also alles was nach "Nachname:" steht. Danach müsste ich das Ergebnis mit der einen Datei mit den 500 Nachnamen vergleichen. Hat jemand eine Idee wie ich das in Unix umsetze?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Wolfgang, 12.03.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Sorry, deine Aufgabenstellung ist mir etwas zweideutig.
    Willst du wissen, ob zu jedem Nachnamen deiner Namensdatei eine passende Steckbrief-datei existiert?
    Oder willst du wissen, ob zu jeder Steckbrief-datei ein Namenseintrag vorliegt?

    Ohne Beispieldaten und Beispielergebnis kann ich nur abstrakt antworten.

    Lies die Namensdatei in ein Array ein, und gehe dann jede Datei durch und frag nach entsprechenden Eintrag im Array ab.
    Damit musst du die Namen nur einmal einlesen.

    Gruß Wolfgang
     
  4. #3 madfool, 12.03.2007
    Zuletzt bearbeitet: 12.03.2007
    madfool

    madfool Tripel-As

    Dabei seit:
    12.08.2004
    Beiträge:
    192
    Zustimmungen:
    0
    Irgendwie sowas:

    Code:
    #!/bin/sh
    
    while read line
    do
       for file in `ls`
       do
          if cat $file | grep "Nachname:" | cut ... # Syntax von cut hab ich gerade nicht im Kopf...
          then
             echo "Datei für $line gefunden"
          fi
       done
    done <FILE
    
    Ungetestet...
     
  5. #4 drm, 12.03.2007
    Zuletzt bearbeitet: 12.03.2007
    drm

    drm Eroberer

    Dabei seit:
    29.08.2006
    Beiträge:
    59
    Zustimmungen:
    0
    @madfool: Werde ich mal testen...

    @Wolfgang: Hier Beispieldaten:

    Hauptliste:
    Mustermann
    Untermann
    Obermann
    Testmann
    usw.

    Steckbriefdatei1:
    Vorname: Max
    Nachname: Mustermann
    Beruf: Verkäufer

    Steckbriefdatei1:
    Vorname: Rudi
    Nachname: Untermann
    Beruf: Verkäufer
    usw.

    Ergebnis sollte dann so aussehen:
    Mustermann - gefunden
    Untermann - fehlt
    usw.

    Erst einmal möchte ich wissen ob zu jeder Steckbriefdatei ein Namenseintrag vorliegt.
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    Hab's mal so probiert:
    Code:
    while read line
    do
       cd $HOME/steckbriefe #hier liegen die Dateien mit den Steckbriefen
       for file in `ls`
       do
          variable=$file | grep "Nachname:" #cut habe ich erst mal weggelassen, muss ich noch schaun wie das funktioniert
          echo $variable #wollte die Nachnamen erst mal nur ausgeben, klappt aber nicht, hier muss später ja eine if-Abfage hin...
       done
    done < Hauptliste
    
    Leider funktioniert selbst so die Ausgabe nicht, need help!
     
  6. #5 Wolfgang, 12.03.2007
    Zuletzt bearbeitet: 12.03.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Hier mein Vorschlag.
    name sei die Namensdatei,
    datei* seien die Steckbriefe:
    Ich habe hier eine Variante gewählt, die jede Datei nur einmal öffnen muss.
    Also arbeite ich mit 2 Arrays, die im Nachgang verglichen(durchsucht) werden.

    Code:
     
    A=($(cat name)); #Array mit Namen
    
    i=0; #Index für Array 2
    
    for d in $(ls ./datei*);
    do 
    N[$i]=$(grep "Nachname:" $d|cut -d" " -f2)&& ((i++));# zählt nur hoch, wenn ein name gefunden wurde. Das vermeidet leere Namen
    done; 
    # Jetzt vergleichen wir:
    for x in ${A[*]}; 
    do 
    echo ${N[*]}|grep -q "$x"; #stummes grep
    if [ $? -eq 0 ]; #Returnwert gibt Auskunft ob gefunden
    then  
    echo "$x vorhanden";
    else 
    echo "$x nicht vorhanden";
    fi;
    done 
    
    Habe jetzt deinen Code noch nicht angesehen, werde das mal nachholen.
    Gruß Wolfgang

    edit zu deinem Code:
    Das geht so nicht.
    wenn du die variable auf das Ergebnis setzt, dann eher so:
    Code:
    variable="$(grep "Nachname" $file);"
    # das macht aber Probleme, wenn grep nicht matcht, dann ist variable leer.
    #Dann prüfen ob variable leer:
    if [ x"$variable == "x" ]; then #*siehe Anmerkung
    echo "Name in $file nicht gefunden";
    else 
    echo "$variable in $file gefunden";
    fi
    
    *Anmerkung: vermeidet Fehler bei leerer Variable
     
  7. drm

    drm Eroberer

    Dabei seit:
    29.08.2006
    Beiträge:
    59
    Zustimmungen:
    0
    Hallo Wolfgang,
    danke für deine super Hilfe. Leider habe ich deinen Vorschlag nicht ans Laufen bekommen, ich nutze übrigens eine ksh.

    Bisher habe ich versucht den Ansatz von madfool weiter auszubauen, dieser sieht inzwischen so aus:
    Code:
    while read line
    do
      cd $HOME/verzeichnis
      for file in 'ls'
        xy=' grep "Nachname:" $file | cut -d ' ' -f3 '
        echo $xy #hier werden die Nachnamen aus den einzelnen Dateien ausgegeben
        echo $line #hier werden die Nachnamen aus der Hauptdatei ausgegeben
    
        if [ x"$xy != x"$line ];
          then echo $line;
        fi
      done
    done < Hauptliste
    
    Problem an meinem Code:
    - in der while-Schleife wird der erste Nachname gezogen, dann wird dieser in der for-Schleife mit allen Nachnamen aus den einzelnen Dateien verglichen
    - die if-Abfrage ist irgendwie blöde gestellt, und zwar trifft der Nachname aus der Hauptdatei mit den Nachnamen aus den einzelnen Dateien so gut wie nie überein, maximal 1 mal und einige hundert mal nicht
    - mein Ziel ist ja nur zu Vergleichen ob irgendwo Abweichungen zu finden sind, so passt es aber nicht
    - außerdem sind die Durchlaufzeiten recht lang, aber das ist nur nebensächlich
    - hat jemand eine Idee wie man meinen Ansatz korrigieren kann, wie gesagt, der eigentliche Abgleich ist "Käse" ;-)
     
  8. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  9. #7 Wolfgang, 12.03.2007
    Zuletzt bearbeitet: 12.03.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Was passiert denn unter ksh mit meinem Skriptvorschlag?
    Ja, ich bin von der bash ausgegeangen, weil du vorher keine Angabe gemacht hast.
    Ich habe eben aus Performancegründen zwei Arrays verwendet.
    Das erspart das wiederholte Einlesen aller Dateien.

    Code:
    xy=' grep "Nachname:" $file | cut -d ' ' -f3 '
    Geht normalerweise nur mit Backticks, oder besser
    Code:
    xy="$(grep "Nachname:" $file | cut -d ' ' -f3 )"
    Ich habe das Beispiel auch nur gebracht, um dich auf deinen Fehler im ersten Versuch hinzuweisen.

    Hier noch ein anderer dirty Schnellhack, der mit GNU grep auch unter ksh laufen sollte:
    Code:
    for i in $(ls datei*);
     do
     N="$(grep -f name $i|cut -d" " -f2)";
     if [ -n "$N" ];then
     echo $N;
    fi;
    done>found;
    echo Gefunden:;
    cat found;
    echo Nicht gefunden:;
    grep -v -f found name
    
    Das sollte auch etwas schneller laufen.
    Allerdings werden hier keine Dateien angezeigt, in denen es keine Nachname: -Zeile mit gültigen Namen gibt.

    Gruß Wolfgang
     
  10. drm

    drm Eroberer

    Dabei seit:
    29.08.2006
    Beiträge:
    59
    Zustimmungen:
    0
    Ich habe es jetzt folgendermaßen hinbekommen:
    Code:
    cd $HOME/verzeichnis
    grep -i "Nachname:" * | cut -d ' ' -f2  > tmp_d
    cd $HOME/
    while read line
    do
       grep -i $line $HOME/verzeichnis/tmp_d 1>/dev/null 2>&1
       rc=$?
       set -e
       if [ $rc -ne 0 ]
       then
         echo "$line" >> ergebnis
         continue
       fi
    done < Hauptliste
    
    Vorteil: So läuft es jetzt sehr performant, da nur noch zwei Dateien verglichen werden. So ähnlich hatte sich das Wolfgang mit den zwei Arrays vorgestellt, nur dass ich mich nicht so mit Arrays unter Unix auskenne...

    Nochmal danke an Wolfgang und madfool für die Hilfe. Thx!!!
     
Thema:

Dateien vergleichen

Die Seite wird geladen...

Dateien vergleichen - Ähnliche Themen

  1. Alle Dateien eines Verzeichnisses mit einer anderen Datei vergleichen

    Alle Dateien eines Verzeichnisses mit einer anderen Datei vergleichen: Hallo, ich habe ein Verzeichnis, darin enthalten sind mehrere Dateien. Nun möchte ich alle Dateien (Parameter $1) gegen eine konstante Datei...
  2. Benötige Hilfe- Dateien vergleichen

    Benötige Hilfe- Dateien vergleichen: Hallo, für eine Arbeit an der Uni muss ich einige viele Bilder miteinander vergleichen, was ich gerne durch eine Automatisierung etwas...
  3. Mit VIM Dateien vergleichen und Unterschiede sichtbar machen

    Mit VIM Dateien vergleichen und Unterschiede sichtbar machen: Hallo, mit VIM ist es recht passabel möglich, zwei Dateien zu vergleichen und die Unterschiede hübsch aufbereitet anzeigen zu lassen: # vim -d...
  4. Bash - Zwei Binärdateien vergleichen (SQL Diff)

    Bash - Zwei Binärdateien vergleichen (SQL Diff): Moin, versuche zwei SQL Dumps miteinander zu vergleichen, dazu hole ich Stammdaten aus der MSSQL-DB und speichere sie direkt unter der Bash in...
  5. Dateien sortieren und dann vergleichen

    Dateien sortieren und dann vergleichen: Hallo, es gibt verschiedene Progrämmchen (möglichst via Kommandozeile und unter Windows) die Dateien vergleichen können. ZB. GNU Tools:...