AWK - je 2 Spalten in 2 txt-Files vergleichen

Dave1701

Cadet 1st Year
Registriert
Sep. 2016
Beiträge
13
Moin zusammen,

ich bin gerade dabei mehrere Dateien zusammenzuführen, die in txt-Format vorliegen.

Ich habe eine Datei mit einer Kunden-ID und einem Datum.
Die zweite Datei enthält diverse Kundeninformationen, inkl. einem Datum und der Kunden-ID.

Ich möchte jetzt, wenn die Kunden-IDs (beide in Spalte 1) gleich sind UND das Datum (Spalte 2) aus Datei 1 kleiner oder gleich dem Datum (Spalte 25) aus Datei 2 ist, diese Zeilen in eine andere Datei schreiben. Hierbei interessieren mich als Output nur die Informationen aus Datei 2.

Beispiel:
Datei 1

Kunde-ID;Datum
123;01.02.2016
345;03.04.2016
567;02.11.2015
894;17.05.2016

Datei 2
Kunde-ID;XX;XX;XX;Datum
123;XX;XX;XX;03.05.2016
345;XX;XX;XX;01.02.2016
345;XX;XX;XX;06.11.2016
567;XX;XX;XX;01.01.2015
567;XX;XX;XX;10.12.2016
567;XX;XX;XX;03.01.2016
894;XX;XX;XX;01.11.2016

Ergebnis:
Kunde-ID;XX;XX;XX;Datum
123;XX;XX;XX;03.05.2016
345;XX;XX;XX;01.02.2016 --> Gelöscht!
345;XX;XX;XX;06.11.2016
567;XX;XX;XX;01.01.2015 --> Gelöscht
567;XX;XX;XX;10.12.2016
567;XX;XX;XX;03.01.2016
894;XX;XX;XX;01.11.2016

Ich habe einen Codeschnipsel gefunden, in dem man je 1 Spalte auf Übereinstimmung prüfen und dann eine Aktion durchführen kann, jedoch funktioniert meine Anpassung nicht auf 2 Spalten je Datei und dann noch mit kleiner oder gleich.

Ich hoffe ihr könnt mir helfen.

Grüße,
David
 
Ich würde 2 Listen anlegen ( List(of) <--bequemer oder Array <-- älter ) und aus den Datensätzen von 1 und 2 jeweils eine Klasse machen.
Dann kannst du schön nach Sachen in der List(of) suchen und als Ergebnis wenn die Bedingungen zutreffen ausgeben.
 
Danke für die Antwort.

Habe mal was zusammengeschrieben, leider funktioniert der Vergleich zwischen den Datumswerten nicht.

Code:
gawk -F";" -v OFS=";" "NR==FNR{a[NR]=$0;next}{for (i in a){split(a[i],x);if (x[1]==$1 && x[2]<$3)print $0}}" file2.txt file1.txt

x[1] ist die Kunden-ID in file2
x[2] ist das Datum in file2
$1 ist die Kunden-ID in file2
$3 ist das Datum in file2

Quelle: http://www.unix.com/shell-programming-and-scripting/242633-awk-arrays-comparing-multiple-columns-across-two-files.html

Das nächste Problem, was ich glaube ich haben werde, ist das Datumsformat in file1. Dieses ist ein Zeitstempel [tt.MM.jjjj hh:mm:ss], in file2 jedoch nur ein Datum [tt.MM.jjjj].
Wobei ich aus dem Datum in file2 einen Zeitstempel machen könnte mit der Uhrzeit 00:00:00, wenn es helfen würde.

Hat jemand eine Idee, was ich an meinem obigen Code verändern muss?


Danke vorab und grüße,
Dave
 
Ich kann dir diese Seite empfehlen. Wenn du nicht klar kommst, einfach noch mal melden ;-)
 
Endoro schrieb:
Ich kann dir diese Seite empfehlen. Wenn du nicht klar kommst, einfach noch mal melden ;-)

Moin moin,

danke für die Hilfe.
Ich habe jetzt schon alles probiert, mit strftime und mktime und bekomme es einfach nicht hin eine Differenz von 2 Datumswerten hinzubekommen -.-
Habe in einer Testdatei jede mögliche Kombination von Datumsformaten ausprobiert. Egal ob mit "-", "/", "." getrennt, mit oder ohne Uhrzeit. Ich bekomme jedes mal einen Dezimalwert heraus, den ich überhaupt nicht nachvollziehen kann.

Hier ein Beispiel, das bei mir ebenfalls nicht funktioniert:
Code:
$ awk -F"," -v OFS=, "{gsub(/-/,/ /,$2);gsub(/-/,/ /,$3);$2=$2/ 0 0 0/;$3=$3/ 0 0 0/;d2=mktime($3);d1=mktime($2);print $1,(d2-d1)/86400}" file1
von der Seite: http://www.theunixschool.com/2013/01/gawk-calculate-date-time-difference-timestamp.html
das letzte Beispiel "difference in days".

Grüße,
Dave
 
Hier eine Lösung in Perl (da es vermutlich eine Linux-Kiste ist liegt die Wahrscheinlichkeit, daß Perl installiert ist bei 99,9%)

datei1:
Code:
123;01.02.2016 23:12:14
345;03.04.2016 08:05:04
567;02.11.2015 14:56:21
894;17.05.2016 18:55:08

datei2:
Code:
123;XX;XX;XX;03.05.2016
345;XX;XX;XX;01.02.2016
345;XX;XX;XX;06.11.2016
567;XX;XX;XX;01.01.2015
333;XX;XX;XX;24.11.2016
567;XX;XX;XX;10.12.2016
567;XX;XX;XX;03.01.2016
894;XX;XX;XX;01.11.2016

Programm:
Code:
#!/usr/bin/perl -w

use Date::Manip;


Date_Init("DateFormat=non-US");

my %kdate= ();

open(my $f1, "datei1") or die "open failed: $!";
while(<$f1>)
{
	my @s= split(";");
	$kdate{$s[0]}= ParseDate($s[1]);
}
close($f1);

print"Kundennummern sortiert:\n-----------------------\n";
for my $k(sort keys %kdate)
{
	printf("%5s : %s\n", $k, $kdate{$k});
}
print"\n";

open (my $of, ">ergebnis") or die "open failed: $!";
open(my $f2, "datei2") or die "open failed: $!";
while(my $line= <$f2>)
{
	my @s= split(";", $line);
	if (exists($kdate{$s[0]}))
	{
		my $date= ParseDate($s[4]);
		my $err;
		my $delta= DateCalc($date, $kdate{$s[0]}, \$err);
		if (Delta_Format($delta, 0, "%st")<0) # Differenz in Sekunden
		{
			print $of $line;
		}
		else
		{
			printf("GELÖSCHT: %s", $line);
		}
	}
	else
	{
		printf("FEHLER: Kundennummer %s gibt es nicht!\n", $s[0]);
	}
}
close($f2);
close($of);

Abspeichern als "extract1.pl".
Ausführbar machen mit
Code:
chmod 700 extract1.pl
und mit
Code:
./extract1.pl
ausführen.

Als Bildschirmausgabe bekommst Du:
Code:
Kundennummern sortiert:
-----------------------
  123 : 2016020123:12:14
  345 : 2016040308:05:04
  567 : 2015110214:56:21
  894 : 2016051718:55:08

GELÖSCHT: 345;XX;XX;XX;01.02.2016
GELÖSCHT: 567;XX;XX;XX;01.01.2015
FEHLER: Kundennummer 333 gibt es nicht!



Und in "ergebnis" steht
Code:
123;XX;XX;XX;03.05.2016
345;XX;XX;XX;06.11.2016
567;XX;XX;XX;10.12.2016
567;XX;XX;XX;03.01.2016
894;XX;XX;XX;01.11.2016


HTH

BigNum
 
@Dave: Also wenn Perl bei dir nicht funktioniert, melde dich einfach. Awk ist einfach zu installieren (man kopiert das einfach), bei Python, Perl, Windows-Powershell & Co. bocken die Admins gerne.
 
Endoro schrieb:
@Dave: Also wenn Perl bei dir nicht funktioniert, melde dich einfach. Awk ist einfach zu installieren (man kopiert das einfach), bei Python, Perl, Windows-Powershell & Co. bocken die Admins gerne.

Hey,

mit Perl kann ich leider nichts anfangen. 1. ist es eine weitere mir fremde Programmiersprache und 2. arbeiten wir mit einem Windowssystem.
Daher tenidere ich zu awk. Die gawk.exe habe ich im gleichen Ordner wie die Rohdaten.
Ein anderes Programm zum verarbeiten der Rohdaten habe ich mittels awk schon geschrieben. Bloß der Vergleich von Datumswerten funktioniert eben nicht.

Soll heißen, ich kann etwas awk, jedenfalls verstehe ich den Quellcode und kann ggf. Anpassungen selber machen.

Für deine Hilfe wäre ich sehr dankbar.

Grüße,
Davd
 
Hey,

Windows: hast du das "richtige" gawk genommen, das liegt hier: http://www.klabaster.com/freeware.htm#mawk

Free download of the version 4.1.3 (May 2015)
of Gawk 4.1.3 (gawk4.zip)

Die Seite sieht etwas "Old School" aus, ist aber absolut i.O.

Ansonsten komm ich heut Abend noch mal vorbei :-)

Gruß, Endoro.
 
Ja, die Version habe ich gawk 4.1.3.

Ok, ich warte :) Danke schonmal für deine Mühe.

Grüße,
Dave
 
Zurück
Oben