Dateien vergleichen

D

drm

Eroberer
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?
 
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
 
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...
 
Zuletzt bearbeitet:
@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!
 
Zuletzt bearbeitet:
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:
variable=$file | grep "Nachname:"
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
 
Zuletzt bearbeitet:
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" ;-)
 
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
 
Zuletzt bearbeitet:
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!!!
 

Ähnliche Themen

Mit Picasa vergebene Tags aus jpg-Dateien auslesen

csv-Datei mit UNIX zurecht stutzen und Daten in xls-Datei laufend abspeichern

Splitten einer Datei (aus einer großen Datei viele kleine machen)

2 Dateien zeilen-weise vergleichen

Dateien in Unterordnern entpacken?

Zurück
Oben