PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : mit Bash Skript Dateien "vergleichen"



wackeldackel
22-06-2007, 07:26
Hallo zusammen,

steh etwas auf der Leitung.

Wie vergleiche ich den Inhalt zweier Dateien mit der Bedingung, dass ich die Zeilen aus Datei1 in der Datei2 suchen möchte.
Datei 1 hat 100 Zeilen und Datei2 hat 5000 Zeilen.
Mit diff geht das nicht, da ich ja teilweise sehr unterschiedliche Inhalte haben (oder ich kann es nicht). Datei2 hat halt viel mehr Zeilen und damit zwischen den Übereinstimmungen auch sehr viele unterschiedliche Zeilen.
Mit diff bekomme ich auch die gleichen Zeilen raus, weil diese in einer anderen Zeilennummer stehen.

z.B.:

Datei1

200801|50000|5109|12|1308|9997
200801|50000|5109|12|2992|2710
200801|50000|5109|12|448|20
200801|50000|5109|12|99|3530
200801|50000|5109|62|1308|9997
200801|50000|5109|62|2992|2710
200801|50000|5109|62|448|20
200801|50000|5109|62|99|1040
200801|50000|5109|72|1308|9997
200801|50000|5109|72|2992|2710
200801|50000|5109|72|448|20
200801|50000|5109|72|99|0106
200801|50069|3211|72|3058|9999
200801|50069|3211|52|3058|9999
200801|50069|3211|32|3058|9999
200801|50069|3211|12|3058|9999
200801|50069|3211|42|3058|9999
200801|50069|3211|72|638|50
200801|50069|3211|52|638|50
200801|50069|3211|32|638|50
200801|50069|3211|12|638|50
200801|50069|3211|42|638|50
200801|50069|3211|72|150|1700
200801|50069|3211|52|150|1700
200801|50069|3211|32|150|1700
200801|50069|3211|12|150|1700
200801|50069|3211|42|150|1700
200801|50069|3211|72|448|20
200801|50069|3211|52|448|20
200801|50069|3211|32|448|20
200801|50069|3211|12|448|20
200801|50069|3211|42|448|20

Datei2

500501|6284|708|88|3064|1925
500501|6284|708|88|323|1925
500501|6284|708|88|3166|88
500501|6284|708|88|99|0455
500501|6284|708|88|113|73
500501|6284|708|88|113|73
200801|50000|5109|62|1308|9997
200801|50000|5109|12|1308|9997
200801|50000|5109|72|1308|9997
200801|50000|5109|62|638|70
200801|50000|5109|12|638|70
200801|50000|5109|72|638|70
200801|50000|5109|62|150|2710
200801|50000|5109|12|150|2710
200801|50000|5109|72|150|2710
200801|50000|5109|62|99|1040
200801|50000|5109|12|99|3530
200801|50000|5109|72|99|0106
200801|50000|5109|62|649|70
200801|50000|5109|12|649|70
200801|50000|5109|72|649|70
200801|50000|5109|62|448|20
200801|50000|5109|12|448|20
200801|50000|5109|72|448|20
200801|50000|5109|62|448|20
200801|50000|5109|12|448|20
200801|50000|5109|72|448|20
200801|50001|3215|12|2992|7124
200801|50001|3215|12|3058|9997
200801|50001|3215|12|448|20
200801|50001|3215|12|99|3761
200801|50001|3215|32|2992|3149
200801|50001|3215|32|3058|9997
200801|50001|3215|32|448|20
200801|50001|3215|32|99|2360
200801|50001|3215|42|2992|6377
200801|50001|3215|42|3058|9997
200801|50001|3215|42|448|20
200801|50001|3215|42|99|4850
200801|50001|3215|52|2992|1172
200801|50001|3215|52|3058|9997
200801|50001|3215|52|448|20
200801|50001|3215|52|99|0360
200801|50069|3211|72|3058|9999
200801|50069|3211|52|3058|9999
200801|50069|3211|32|3058|9999
200801|50069|3211|12|3058|9999
200801|50069|3211|42|3058|9999
200801|50069|3211|72|638|50
200801|50069|3211|52|638|50
200801|50069|3211|32|638|50
200801|50069|3211|12|638|50
200801|50069|3211|42|638|50
200801|50069|3211|72|150|1700
200801|50069|3211|52|150|1700
200801|50069|3211|32|150|1700
200801|50069|3211|12|150|1700
200801|50069|3211|42|150|1700
200801|50069|3211|72|448|20
200801|50069|3211|52|448|20
200801|50069|3211|32|448|20
200801|50069|3211|12|448|20
200801|50069|3211|42|448|20

Wie bekomme ich das am einfachsten hin ???

wackeldackel
22-06-2007, 09:47
Hallo,

hat sich (fast) erledigt. Habe doch noch was auf die Reihe bekommen.
Zwar nicht schön, aber läuft schon mal.


z=0;
for i in $(cat datei2)
do
((++z));
# die Datei mit den zu suchenden Zeilen in einer Schleife einlesen und mit grep
# die zweite Datei durchsuchen lassen. Wenn er keine Zeile findet landet die
# gesuchte Zeile in einer Datei.

zeile=`cat datei3 | grep "$i" | wc -l`;

if [ "$zeile" == "0" ]
then echo $i >> tralala.txt
fi
done


ABER

Auf meinem Rechner ergibt eine nicht gefundene Zeile mit wc -l = "0"
auf dem Server wird daraus " 0"

Wie bekomme ich die Leerzeichen weg ???

rais
22-06-2007, 11:23
Moin moin,


zeile=`cat datei3 | grep "$i" | wc -l`;

if [ "$zeile" == "0" ]
then echo $i >> tralala.txt
fi
done


ABER

Auf meinem Rechner ergibt eine nicht gefundene Zeile mit wc -l = "0"
auf dem Server wird daraus " 0"

Wie bekomme ich die Leerzeichen weg ???
wie wär's mit


zeile=`grep "$i" datei3`
test -z "$zeile" && echo "$i" >> tralala.txt
?
MfG,

wackeldackel
23-06-2007, 12:01
Hallo rais,

jepp, einwandfrei !!! :D

Danke

wackeldackel

jan61
27-06-2007, 16:53
Moin,


Moin moin,

wie wär's mit


zeile=`grep "$i" datei3`
test -z "$zeile" && echo "$i" >> tralala.txt
?
MfG,

grep lässt sich benutzen, um das (Nicht-)Vorhandensein von Suchmustern zu melden. Außerdem würde ich vorsichtshalber die ganze Zeile vergleichen, sonst kann es passieren, dass "123|456|789" als Treffer gewertet wird, obwohl in datei3 nur die Zeile "0123|456|7890" steht:

grep -q "^$i$" datei3 || echo "$i" >>tralala.txtBei großen Dateien hat das zeilenweise Auslesen aber einen entscheidenden Nachteil: Je Zeile wird ein neuer Prozess (grep) gestartet, was ganz schön auf die Performance gehen kann. Schneller ist (sofern die Zeilenreihenfolge in der Ausgangsdatei keine Rolle spielt), das Sortieren und Arbeiten mit einem Vergleichstool:

sort datei1 >datei1.sort
sort datei2 >datei2.sort
comm -23 datei1.sort datei2.sort >ergebnis.txt
rm datei[12].sortcomm ist ein wenig bekanntes Werkzeug, dass sich aber für solche Fälle prima gebrauchen lässt. Die Option -23 unterdrückt die Ausgabe aller Zeilen, die nur in datei2 oder aber in beiden Dateien auftauchen. Ergebnis ist eine Liste der Zeilen, die ausschließlich in datei1 vorhanden sind.

Jan

wackeldackel
28-06-2007, 04:15
Morg'n Jan,

comm kenn ich auch nicht (Asche auf mein Haupt).
Die Idee ist super, werde ich heute gleich mal testen.

Danke

Wackeldackel