ubuntuusers.de

Liste aktualisieren

Status: Gelöst | Ubuntu-Version: Kubuntu 11.04 (Natty Narwhal)
Antworten |

Nobuddy

Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Hallo zusammen,

ich möchte bestimmte Spalten einer Liste anhand einer anderen Liste aktualisieren.

Diese Liste hat folgendes Format

L-Nr=1
Artikel-Nr=2
Benennung=3
Benennung2=4
Hersteller=5
Hersteller-Nr=6
PE=7
VE=8
MwSt-Gruppe=9
Menge=10
Ek=11
Vk=12
Menge2=13
Ek2=14
Vk2=15
Menge3=16
Ek3=17
Vk3=18
Gewicht=19
EAN=20
Hauptgruppe=21
Untergruppe=22
Seite=23
Seitenzusatz=24
Lagerstatus=25
AbZeile=26

und sieht so aus (mit ein paar Beispieldaten)

120	88814980	HEWLETT-PACKARD HP DESKJET 3-FARB-PATRONE C6578A	HEWLETT-PACKARD HP DESKJET 3-FARB-PATRONE C6578A NR.78 38ML	HEWLETT-PACKARD	C6578A	ST		2			-	3		-		-	-		0088698993095	110	110	60		LAGER
28	819878	HP TINTENPATRONE C6578AE 38ML 78 FARBIG			C6578AE	STK	1	2	1		-	5		-		-	-		0088698993088	1	32	13	A	LAGER
48	3175164501	ORIGINAL TINTE HP 45 (51645AE) FüR HP, 42 ML, SCHWARZ	ORIGINAL TINTE HP 45 (51645AE) FüR HP, 42 ML, SCHWARZ(OEM 51645AE)FüR: DESKJET 120C/710C/712C/720C/722C/750/750C/755/755C/810C/815C/820C/820CSE/820CXI/830C/832C/850C/850CXI/855C/855CSE/855CXI/870C/870CSE/870CXI/870CSI/880C/882C/890C/890CSE/890CXI/890CSE/895C/895CXI/895CSE/930C/930CM/932C/	HP	51645AE		1	1	1		-	3		-	6	-	-	18	0088698603635	TINTENSTRAHLDRUCKER-ZUBEHöR, ORIGINAL	TINTENPATRONEN, HP	THEMENKATALOG	827	DIREKT
120	88814945	HEWLETT-PACKARD HP DESKJET TINTENPATRONE 51645A SW	HEWLETT-PACKARD HP DESKJET TINTENPATRONE 51645A SW 	HEWLETT-PACKARD	51645AE	ST		2			-	3		-		-	-		0088698603642	110	110	60		LAGER
28	366676	HP TINTENPATRONE 51645AE 45 SCHWARZ			51645AE	STK	1	2	1		-	5		-		-	-		0088698200292	1	32	12	A	LAGER
48	4206051	ORIGINAL TONER FüR SAMSUNG LASERDRUCKER ML1510, SCHWARZ	ORIGINAL TONER FüR SAMSUNG LASERDRUCKER ML1510, SCHWARZKAPAZITäT: 3.000 SEITEN(ML1710D3)ML1410/ML1500/ML1510B/ML1710/ML1710B/ML1710D/ML1710P/ML1750/ ML1740/ML1755	SAMSUNG	ML1710D3		1	1	1		-	2		-	4	-	-	18		LASERDRUCKER-ZUBEHöR, ORIGINAL	LASERDRUCKER-ZUBEHöR, SAMSUNG	THEMENKATALOG	749	DIREKT
120	88816946	SAMSUNG SAMSUNG TONER SW F.ML-1410/1510/	SAMSUNG SAMSUNG TONER SW F.ML-1410/1510/ 1710/1750	SAMSUNG	ML1710D3SEE	ST		2			-	3		-		-	-		8803821704032	160	160	81		LAGER
28	386210	SAMSUNG TONER ML1710D3/ELS SCHWARZ			ML1710D3ELS	STK	1	2	1		-	3		-		-	-		8803821704032	1	64	35	A	LAGER
48	4206087	ORIGINAL TONER FüR SAMSUNG LASERDRUCKER ML 2010, SCHWARZ	ORIGINAL TONER FüR SAMSUNG LASERDRUCKER ML 2010, SCHWARZKAPAZITäT: CA. 3.000 SEITEN(ML-2010D3)ML2010R/ML2510/ML2571/ML2571N/ML2570,	SAMSUNG	ML2010D3		1	1	1		-	2		-	4	-	-	18		LASERDRUCKER-ZUBEHöR, ORIGINAL	LASERDRUCKER-ZUBEHöR, SAMSUNG	THEMENKATALOG	749	DIREKT
120	88818076	SAMSUNG SAMSUNG TON.F.ML-2010/2510 SW 3000S	SAMSUNG SAMSUNG TON.F.ML-2010/2510 SW 3000S 	SAMSUNG	ML2010D3SEE	ST		2			-	3		-		-	-		8808979610624	160	160	82		LAGER
28	764821	SAMSUNG TONER ML2010D3/ELS SCHWARZ			ML2010D3ELS	STK	1	2	1		-	3		-		-	-		8808979610624	1	64	35	A	LAGER

Bei dem Lieferant 028 sind in der Spalte Hersteller keine Einträge und diese Spalte Hersteller möchte ich aktualisieren.

Ich habe eine Datei liste0280.txt erstellt, in der sich nur Daten vom Lieferanten 028 befinden, die auch eine EAN-Nummer haben. In der ersten Spalte von liste0280.txt, habe ich die EAN-Nummer gekürzt, so daß nur die ersten 7 Stellen von links, sich dort befinden. Die ersten 2 Stellen sind der Ländercode, die andern 5 Stellen, der Herstellercode.

Diese liste0280.txt sieht dann mit den obigen Beispieldaten, so aus

0088698	819878	HP TINTENPATRONE C6578AE 38ML 78 FARBIG			C6578AE	STK	1	2	1		-	5		-		-	-		0088698993088	1	32	13	A	LAGER
0088698	366676	HP TINTENPATRONE 51645AE 45 SCHWARZ			51645AE	STK	1	2	1		-	5		-		-	-		0088698200292	1	32	12	A	LAGER
8803821	386210	SAMSUNG TONER ML1710D3/ELS SCHWARZ			ML1710D3ELS	STK	1	2	1		-	3		-		-	-		8803821704032	1	64	35	A	LAGER
8808979	764821	SAMSUNG TONER ML2010D3/ELS SCHWARZ			ML2010D3ELS	STK	1	2	1		-	3		-		-	-		8808979610624	1	64	35	A	LAGER

Als nächstes habe ich eine Datei LISTE_EANH_048.txt erstellt. In der ersten Spalte ist die gekürzte EAN-Nummer (7 Stellen von links) und die zweite Spalte der dazu gehörige Hersteller.

Diese LISTE_EANH_048.txt sieht so aus (Beispieldaten)

0025184	HP
0088698	HP
0725184	HP
0808736	HP
0829160	HP
0882780	HP
0883585	HP
0884420	HP
0884962	HP
0885631	HP
3141725	HP
3540260	HP
4016138	HP
7613058	HP
8844201	HP
8844205	HP
8849621	HP
8849626	HP
8856316	HP
8856318	HP
0635753	SAMSUNG
8803821	SAMSUNG
8806071	SAMSUNG
8808979	SAMSUNG
8808987	SAMSUNG
8808993	SAMSUNG

Nun möchte ich die Herstellerspalte der liste0280.txt, anhand der LISTE_EANH_048.txt abgleichen, soweit die EAN-Kurznummer (7 Stellen von links) identisch sind.

Dazu habe ich folgendes awk-Script erstellt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      		# Tabulator als Eingabe-Trenner
	OFS="\t";							# Tabulator als Ausgabe-Trenner

	i=1;
	while(getline < "LISTE_EANH_048.txt")  {			# lies zeilenweise die EAN-Datei ein
		bEAN[i]= $1;					        # gekürzter EAN-Code (7 Stellen von links)
		Hersteller[i]= $2;
		i++;
		}
	}									


FILENAME ~ "liste0280.txt" {						# Lieferantendatei für Bearbeitung
		hEAN= $1;
    Hersteller[hEAN]= $5
		for(i=1;bEAN[i];i++) {
			if( (bEAN[i] = hEAN) ) {
					gsub("",Hersteller[i],$5);
					gsub($1,"028",$1);
					print;
					break;
				}
			}
	}

Leider funktioniert das nicht so, wie ich es mir vorgestellt habe, es erscheint überall der gleiche Hersteller, was falsch ist.

So sollte es sein: Ist der gekürzte EAN-Code beider Dateien identisch, so ersetze die leere Herstellerspalte durch Hersteller[i], danach ersetze die erste Spalte wieder durch die Lieferanten-Kurznummer.

Das Ergebnis, sollte so aussehen

028	819878	HP TINTENPATRONE C6578AE 38ML 78 FARBIG		HP	C6578AE	STK	1	2	1		-	5		-		-	-		0088698993088	1	32	13	A	LAGER
028	366676	HP TINTENPATRONE 51645AE 45 SCHWARZ		HP	51645AE	STK	1	2	1		-	5		-		-	-		0088698200292	1	32	12	A	LAGER
028	386210	SAMSUNG TONER ML1710D3/ELS SCHWARZ		SAMSUNG	ML1710D3ELS	STK	1	2	1		-	3		-		-	-		8803821704032	1	64	35	A	LAGER
028	764821	SAMSUNG TONER ML2010D3/ELS SCHWARZ		SAMSUNG	ML2010D3ELS	STK	1	2	1		-	3		-		-	-		8808979610624	1	64	35	A	LAGER

Ich hoffe, daß Ihr mir da weiterhelfen könnt und freue mich auch auf Alternativen!

Grüße Nobuddy

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

So heute Morgen habe ich mal was anderes versucht, das wie folgt aussieht

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash

zielpool="$HOME/Privatpost/lieferaktuell"	# Ziel
datenbereit="$HOME/Privatpost/Import_Work"	# Quelle

wert=$(cat LISTE_EANH_048.txt)
teilean0=$(cat  LISTE_EANH_048.txt | awk -F"\t" '{print $1,$2}')
datei=$(cat "$zielpool/liste0280.txt")


zeilenwert=$(cat "$zielpool/liste0280.txt" | wc -l)
zeile=$zeilenwert

while [ $zeile -gt 0 ]; do
	line="$(cat "$zielpool/liste0280.txt" | awk 'NR == '$zeile'')"
	for i in "$line"; do
		zzeile=$(cat LISTE_EANH_048.txt | wc -l)
		while [ $zzeile -gt 0 ]; do
			echo $zzeile
			teil1=$(cat LISTE_EANH_048.txt | awk 'NR == '$zzeile'' | awk -F"\t" '{print $1}')
			teil2=$(cat LISTE_EANH_048.txt | awk 'NR == '$zzeile'' | awk -F"\t" '{print $2}')
			echo "teil1=$teil1"
			ja=$(echo "$line" | grep "$teil1")
			ja=$!
			if [ "$ja" = "0" ]; then
				awk 'gsub("", $teil2, $5)' "$line"
			fi
			zzeile=$((zzeile - 1))
		done
	done
	zeile=$((zeile - 1))
done

Nach einem ersten Testlauf, denke ich daß es funktionieren dürfte ..., habe es aber nach 10 Minuten abgebrochen, da jede einzelne Zeile von liste0280.txt mit den kompletten Daten von LISTE_EANH_048.txt abgeglichen wird.

Das ist wohl doch sehr umständlich, was bestimmt besser geht.

Als nächstes, habe ich das Script, so umgebaut

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash

zielpool="$HOME/Privatpost/lieferaktuell"	# Ziel
datenbereit="$HOME/Privatpost/Import_Work"	# Quelle

wert=$(cat LISTE_EANH_048.txt)
teilean0=$(cat  LISTE_EANH_048.txt | awk -F"\t" '{print $1,$2}')
datei=$(cat "$zielpool/liste0280.txt")


zeilenwert=$(cat "$zielpool/liste0280.txt" | wc -l)
zeile=$zeilenwert

while [ $zeile -gt 0 ]; do
	line="$(cat "$zielpool/liste0280.txt" | awk 'NR == '$zeile'')"
	for i in "$line"; do
			teil0=$(cat "$zielpool/liste0280.txt" | awk -F"\t" '{print $1}')
			teil1=$(cat LISTE_EANH_048.txt | grep "$teil0" | awk -F"\t" '{print $1}' | sort -u)
			teil2=$(cat LISTE_EANH_048.txt | grep "$teil0" | awk -F"\t" '{print $2}' | sort -u)
			echo "teil1=$teil1"
			ja=$(echo "$line" | grep "^$teil1")
			ja=$!
			if [ "$ja" = "0" ]; then
				awk 'gsub("", $teil2, $5)' "$line"
			fi
	done
	zeile=$((zeile - 1))
done

Ist wahrscheinlich auch noch nicht das Optimale.

Weil der Scriptlauf auch hier viel zu lange dauert, habe ich das Script weiter verändert

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

zielpool="$HOME/Privatpost/lieferaktuell"	# Ziel
datenbereit="$HOME/Privatpost/Import_Work"	# Quelle

wert=$(cat LISTE_EANH_048.txt)
teilean0=$(cat  LISTE_EANH_048.txt | awk -F"\t" '{print $1,$2}')
datei=$(cat "$zielpool/liste0280.txt")


zeilenwert=$(cat "$zielpool/liste0280.txt" | wc -l)
zeile=$zeilenwert

while [ $zeile -gt 0 ]; do
	line="$(cat "$zielpool/liste0280.txt" | awk 'NR == '$zeile'')"
	for i in "$line"; do
		teil0=$(cat "$zielpool/liste0280.txt" | awk -F"\t" '{print $1}')
		teil1=$(cat LISTE_EANH_048.txt | grep "$teil0" | awk -F"\t" '{print $1}' | sort -u)
		teil2=$(cat LISTE_EANH_048.txt | grep "$teil0" | awk -F"\t" '{print $2}' | sort -u)
		ja=$!
		if [ "$ja" = "0" ]; then
			awk 'gsub("", $teil2, $5)' "$line"
		fi
                break
	done
	zeile=$((zeile - 1))
done

Wenn Ihr mir Tips oder Vorschläge dazu habt ..., nur zu!

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Also, für mein Empfinden ist die bash für sowas schrecklich umständlich. - würde ich dafür nicht nehmen.

Bei Deinem 1. Entwurf oben hattest Du 2 Arrays aufgebaut, wo der Index einfach durchgezählt wird.
Das geht vielleicht auch, ist aber auf jeden Fall fehleranfällig und nicht sehr schnell.

Deshalb würde ich vorschlagen, direkt die gekürzte EAN als Index zu nehmen, dann wird die Geschichte ziemlich einfach und schnell:

#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      	# Eingabe-Trenner
	OFS="\t";					      	# Ausgabe-Trenner

	while(getline < "LISTE_EANH_048.txt")  {		# lies zeilenweise die Hersteller-Datei
		hersteller[$1]= $2;				# in ein Array, mit der gekürzten EAN als Index
		}
	}									


	{
	if( $5 == "" )  {					# wenn der Hersteller fehlt:
		kurzEAN= substr($20,1,7);				# gekürzte EAN erzeugen

		if (hersteller[kurzEAN] == "")  {			# wenn er keinen Hersteller findet, Fehlermeldung: 
			print "für EAN " kurzEAN "xxxxxx fehlt der Hersteller in LISTE_EANH_048.txt"  >  "/dev/stderr"
			}
		else  	$5= hersteller[kurzEAN];			# wenn doch, den Hersteller aus dem Array in Feld 5 einsetzen
		}
	print $0;						# drucken
	}

wie gewohnt mit dem Aufruf

./herstellerpatch028  liste0280.txt  >  liste0282.txt 

LG,

track

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Hallo track,

da hast Du Recht, in der Bash ist das umständlich und falsche Ergebnisse nicht ausgeschlossen.

Mein letzter Stand ist dieser

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash

zielpool="$HOME/Privatpost/lieferaktuell"	# Ziel
datenbereit="$HOME/Privatpost/Import_Work"	# Quelle

wert=$(cat LISTE_EANH_048.txt)
teilean0=$(cat  LISTE_EANH_048.txt | awk -F"\t" '{print $1,$2}')
datei=$(cat "$zielpool/liste0280.txt")

teil1=$(cat LISTE_EANH_048.txt | awk -F"\t" '{print $1}' | sort -u)
line="$(cat "$zielpool/liste0280.txt" | grep "$teil1" | sort)"

zeilenwert=$(cat "$zielpool/liste0280.txt" | grep "$teil1" | sort | wc -l)
zeile=$zeilenwert

while [ $zeile -gt 0 ]; do
	line="$(cat "$zielpool/liste0280.txt" | sort | awk 'NR == '$zeile'' | grep "$teil1")"
	for i in "$line"; do
		echo "$i"
		teil0=$(echo $i | sort | awk -F" " '{print $1}')
		echo "$teil0"
		aktuell=$(cat LISTE_EANH_048.txt | sort -u | grep "$teil0" | awk -F"\t" '{print $2}')
		echo "$aktuell"
		if [ "$aktuell" != "" ]; then
			echo "$i" | sed 's/'$teil0'/'$aktuell'/g' >> "$zielpool/listeneu.txt"
		fi
		break
	done
	zeile=$((zeile - 1))
	echo $zeile
done

Sieht schon etwas besser aus, allerdings schreibe ich den Hersteller, in die erste Spalte wo die Kurz-EAN drin steht.

Versuche, gleich den Hersteller an den richtigen Platz (Spalte 5) zu setzen, schlugen fehl.

Werde gleich mal Deinen Vorschlag ausprobieren.

Grüße Nobuddy

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Hey track 👍

funktioniert tadellos und vor allem in einem Bruchteil der Zeit, als wie mit meinem Bash-Script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      	# Eingabe-Trenner
	OFS="\t";					      	# Ausgabe-Trenner

	while(getline < "LISTE_EANH_048.txt")  {		# lies zeilenweise die Hersteller-Datei
		hersteller[$1]= $2;				# in ein Array, mit der gekürzten EAN als Index
		}
	}									


FILENAME ~ "liste0280.txt"	{
	if( $5 == "" )  {					# wenn der Hersteller fehlt:
		kurzEAN= substr($20,1,7);				# gekürzte EAN erzeugen

		if (hersteller[kurzEAN] == "")  {			# wenn er keinen Hersteller findet, Fehlermeldung: 
			print "für EAN " kurzEAN "xxxxxx fehlt der Hersteller in LISTE_EANH_048.txt"  >  "/dev/stderr"
			}
		else  	$5= hersteller[kurzEAN];			# wenn doch, den Hersteller aus dem Array in Feld 5 einsetzen
		}
	print $0;						# drucken
	}

Ich habe ja langen mit einem awk-Script es versucht, dies hin zu bekommen, aber meine Konstrukte waren viel komplizierter als Deines. Habe mir es einige male angeschaut, fange jetzt langsam an zu verstehen, wie es funktioniert. Daß es so einfach sein kann ...

Ich habe da noch ein Frage, aus einem vorherigen Post von Dir.

Melde mich per PN bei Dir.

Grüße und Danke

Nobuddy

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Hallo track,

habe gleich eine weitere Aktualisierung der Liste vorgenommen, dabei geht es um die Vereinheitlichung von Herstellernamen.

Die Basisliste sieht so aus (Auszug)

HP	HEWLETT-PACKARD
HP	HEWLETT-PACKARD-COMPANY
HP	HEWLETT-PACKARD-GMBH
HP	HP
SAMSUNG	SAMSUNG
SANFORD	SANFORD
SAUNDERS	SAUNDERS
SAX	SAX
SCHNEIDER-NOVUS	NOVUS
SCHNEIDER-NOVUS	SCHNEIDER
SCHNEIDER-NOVUS	SCHNEIDER-NOVUS

Mit diesem awk-Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      	# Eingabe-Trenner
	OFS="\t";					      	# Ausgabe-Trenner

	while(getline < "LISTEGRUND_HERSTELLER.txt")  {		# lies zeilenweise die Hersteller-Datei
		hersteller[$2]= $1;				# in ein Array, mit der gekürzten EAN als Index
		}
	}									


FILENAME ~ "liste.txt"	{
	if( ($5 != "") )  {					# wenn der Hersteller fehlt:
		bezH= $5;				# gekürzte EAN erzeugen
		if (hersteller[bezH] == "")  {			# wenn er keinen Hersteller findet, Fehlermeldung: 
			print "Kein Eintrag für " bezH " in LISTEGRUND_HERSTELLER.txt"  >  "/dev/stderr"
			}
		else  	$5= hersteller[bezH];			# wenn doch, den Hersteller aus dem Array in Feld 5 einsetzen
		}
	print $0;						# drucken
	}

END { exit 0 }

, aktualisiere ich nun die Spalte Hersteller in meiner Gesamtliste anhand der Basisliste.

Jetzt habe ich auch verstanden, wie das funktioniert. 😉

Grüße und Danke

Nobuddy

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Ich muß jetzt doch noch mal an meinen letzten Post anhängen, da es diesmal doch nicht so funktioniert, wie erwartet.

Habe dies erst heute festgestellt, als ich den Hersteller "Hewlett Packard", der als "HP" bei der Herstellerspalte drin stehen sollte.

In der zuvor erwähnten Hersteller-Basisliste "LISTEGRUND_HERSTELLER.txt", steht bei "HP" folgende Einträge drin

HP	HEWLETT-PACKARD
HP	HEWLETT-PACKARD-COMPANY
HP	HEWLETT-PACKARD-GMBH
HP	HP

Wenn in der Herstellerspalte der Lieferantenliste, ein Eintrag wie in der zweiten Spalte der Hersteller-Basisliste ist, sollte dieser durch den Eintrag aus der ersten Spalte ersetzt werden, was er aber im Moment bei diesem awk-Script nicht tut

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      	# Eingabe-Trenner
	OFS="\t";					      	# Ausgabe-Trenner

	while(getline < "LISTEGRUND_HERSTELLER.txt")  {		# lies zeilenweise die Hersteller-Datei
		hersteller[$2]= $1;				# in ein Array, mit der gekürzten EAN als Index
		}
	}									


FILENAME ~ "liste.txt"	{
	if( ($5 != "") )  {					# wenn der Hersteller fehlt:
		bezH= $5;				# gekürzte EAN erzeugen
		if ( hersteller[bezH] != "" )  {			# wenn er keinen Hersteller findet, Fehlermeldung: 
			$5= hersteller[bezH];			# wenn doch, den Hersteller aus dem Array in Feld 5 einsetzen
			}
		}
	print $0;						# drucken
	}

Habe das Script etwas gekürzt, da ich keine Fehlerausgabe über Einträge die in der Hersteller-Basisliste nicht vorhanden sind, nicht brauche.

Zur Info, ich habe in der Lieferantenliste, wie auch in der Hersteller-Basisliste, das gleiche Format in der Herstellerspalte (Grossbuchstaben; Leerzeichen werden duch Bindestrich ersetzt).

Bindestrich und Minuszeichen auf der Tastatur sollten doch das Gleiche sein, oder?

Hier mal speziel ein Auszug der HP-Zeilen, aus der Lieferantenliste.

120	10530938	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN HP Q1961A 90G  A2	HEWLETT-PACKARD	Q1961A	PAK		2											808736333726	8000	8000	0		LAGER
120	10532926	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT HP C9704A	HEWLETT-PACKARD	C9704A	ST		2				3		3					88698453292	0160	0160	75		LAGER
120	10541798	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ HP CC530AD	HEWLETT-PACKARD	CC530AD	PAK		2				3		3					884420242611	0160	0160	76		LAGER
120	10541804	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ HP CD971AE	HEWLETT-PACKARD	CD971AE	ST		2				3		3					884420649205	0110	0110	62		LAGER
120	10541805	HEWLETT-PACKARD HP TP  NR. 920XL CYAN	HEWLETT-PACKARD HP TP  NR. 920XL CYAN HP CD972AE	HEWLETT-PACKARD	CD972AE	ST		2				3		3					884420649274	0110	0110	62		LAGER
120	10541806	HEWLETT-PACKARD HP TP NR. 920XL MAG.	HEWLETT-PACKARD HP TP NR. 920XL MAG. HP CD973AE	HEWLETT-PACKARD	CD973AE	ST		2				3		3					884420649342	0110	0110	62		LAGER
120	10541807	HEWLETT-PACKARD HP TP NR. 920XL YELLOW	HEWLETT-PACKARD HP TP NR. 920XL YELLOW HP CD974AE	HEWLETT-PACKARD	CD974AE	ST		2				3		3					884420649410	0110	0110	62		LAGER

Hoffe, daß mir jemand von Euch da weiterhelfen kann.

Was ist falsch an obigem awk-Script?

Grüße Nobuddy

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Solchen Filterkrempel würde ich nicht mit Array-Zuweisungen machen, sondern besser mit Regulären Ausdrücken.
Sonst reicht ein einziges Leerzeichen, das anders steht, und es geht nicht mehr.

Also in Deinem Fall würde ich vorschlagen:

subst("HEWLETT.*PACKARD.*","HP",$3);

für awk, ob Feld 3 richtig ist, musst Du mal gucken. Oder doch wieder mit sed :

s/HEWLETT.*PACKARD[[:print:]]*/HP/

LG,

track

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Hallo track,

habe dafür speziell diese Hersteller-Basisliste erstellt, die in der ersten Spalte den Herstellerkurznamen, der in der Herstellerspalte in der Lieferantenliste dann erscheinen soll. In der zweiten Spalte, werden verschiedene Namensauslegungen, wie z.B. "HEWLETT-PACKARD; HEWLETT-PACKARD-COMPANY oder HEWLETT-PACKARD-GMBH" für den Herstellerkurznamen z.B. "HP" geführt.

Die Hersteller-Basisliste, basiert auf Grundlage der verschiedenen Lieferantenliste, die auch wenn nötig angepasst wird.

Eine manuelle Erstellung aller großen Hersteller und deren Variationen, in Deinem ersten bzw. zweiten Beispiel, wäre für mich nicht sinnvoll, da bei Änderung von Herstellernamen es mehr Zeitaufwand wäre, in einem Script solches zu ändern als in einer speziellen Liste.

Ich habe genau das Beispiel mit "HP" oben verwendet, da die Namensgebung des Herstellers in der Lieferantenliste identisch mit der Hersteller-Basisliste (zweite Spalte) ist.

Ein Unterschied zwischen Bindestrich und Minuszeichen auf der Tastatur dürfte es nicht geben, oder?

Stimmt das Script für die Anwendung generell nicht, bzw. wo liegt der Fehler?

Hast Du evtl. eine Idee, damit ich diese Hersteller-Basisliste einsetzen kann?

Grüße Nobuddy

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Guten Abend zusammen,

ich habe jetzt mal die von mir geposteten Beispieldateien mit dem awk-Script getestet.

Die Lieferantenliste "l.txt"

120	10530938	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN HP Q1961A 90G  A2	HEWLETT-PACKARD	Q1961A	PAK		2											808736333726	8000	8000	0		LAGER
120	10532926	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT HP C9704A	HEWLETT-PACKARD	C9704A	ST		2				3		3					88698453292	0160	0160	75		LAGER
120	10541798	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ HP CC530AD	HEWLETT-PACKARD	CC530AD	PAK		2				3		3					884420242611	0160	0160	76		LAGER
120	10541804	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ HP CD971AE	HEWLETT-PACKARD	CD971AE	ST		2				3		3					884420649205	0110	0110	62		LAGER
120	10541805	HEWLETT-PACKARD HP TP  NR. 920XL CYAN	HEWLETT-PACKARD HP TP  NR. 920XL CYAN HP CD972AE	HEWLETT-PACKARD	CD972AE	ST		2				3		3					884420649274	0110	0110	62		LAGER
120	10541806	HEWLETT-PACKARD HP TP NR. 920XL MAG.	HEWLETT-PACKARD HP TP NR. 920XL MAG. HP CD973AE	HEWLETT-PACKARD	CD973AE	ST		2				3		3					884420649342	0110	0110	62		LAGER
120	10541807	HEWLETT-PACKARD HP TP NR. 920XL YELLOW	HEWLETT-PACKARD HP TP NR. 920XL YELLOW HP CD974AE	HEWLETT-PACKARD	CD974AE	ST

Die Hersteller-Basisliste "h.txt"

HP	HEWLETT-PACKARD
HP	HEWLETT-PACKARD-COMPANY
HP	HEWLETT-PACKARD-GMBH
HP	HP
SAMSUNG	SAMSUNG
SANFORD	SANFORD
SAUNDERS	SAUNDERS
SAX	SAX
SCHNEIDER-NOVUS	NOVUS
SCHNEIDER-NOVUS	SCHNEIDER
SCHNEIDER-NOVUS	SCHNEIDER-NOVUS

Das awk-Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /usr/bin/awk -f
	
BEGIN { FS="\t";					      	# Eingabe-Trenner
	OFS="\t";					      	# Ausgabe-Trenner

	while(getline < "/home/benutzer/ordner/h.txt")  {		# lies zeilenweise die Hersteller-Datei
		hersteller[$2]= $1;				# in ein Array, mit der gekürzten EAN als Index
		}
	}									


FILENAME ~ "l.txt"	{
	if( ($5 != "") )  {					# wenn der Hersteller fehlt:
		bezH= $5;				# gekürzte EAN erzeugen
		if ( hersteller[bezH] != "" )  {			# wenn er keinen Hersteller findet, Fehlermeldung: 
			$5= hersteller[bezH];			# wenn doch, den Hersteller aus dem Array in Feld 5 einsetzen
			}
		}
	print $0;						# drucken
	}

END { exit 0 }

Der Befehl

1
2
cd /ordner/zum/awk-script
./edit120HERSTELLERawk /home/whtb/Privatpost/lieferaktuell/* > /home/whtb/Privatpost/lieferaktuell/lneu.txt

Hier arbeitet das awk-Script richtig und das Ergebnis in der neu erstellte Datei "lneu.txt", ist so wie es sein sollte.

120	10530938	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN	HEWLETT-PACKARD INKJETPAPIER 100BL GESTRICHEN HP Q1961A 90G  A2	HP	Q1961A	PAK		2											808736333726	8000	8000	0		LAGER
120	10532926	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT	HEWLETT-PACKARD HP TROMMELEINHEIT+TRANSFEREINHEIT HP C9704A	HP	C9704A	ST		2				3		3					88698453292	0160	0160	75		LAGER
120	10541798	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ	HEWLETT-PACKARD LASERTONER HP CC530AD 2ST SCHWARZ HP CC530AD	HP	CC530AD	PAK		2				3		3					884420242611	0160	0160	76		LAGER
120	10541804	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ	HEWLETT-PACKARD HP TP  NR. 920 SCHWARZ HP CD971AE	HP	CD971AE	ST		2				3		3					884420649205	0110	0110	62		LAGER
120	10541805	HEWLETT-PACKARD HP TP  NR. 920XL CYAN	HEWLETT-PACKARD HP TP  NR. 920XL CYAN HP CD972AE	HP	CD972AE	ST		2				3		3					884420649274	0110	0110	62		LAGER
120	10541806	HEWLETT-PACKARD HP TP NR. 920XL MAG.	HEWLETT-PACKARD HP TP NR. 920XL MAG. HP CD973AE	HP	CD973AE	ST		2				3		3					884420649342	0110	0110	62		LAGER
120	10541807	HEWLETT-PACKARD HP TP NR. 920XL YELLOW	HEWLETT-PACKARD HP TP NR. 920XL YELLOW HP CD974AE	HP	CD974AE	ST

Warum nur funktioniert es nicht auch so mit der richtigen Lieferantendatei?

Das Format und alles sonst, ist identisch mit der Beispieldatei.

Kann es daran liegen, daß die Lieferantendatei ca. 83.000 Zeilen, also Datensätze hat?

Oder liegt es an etwas anderem?

Grüße Nobuddy

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Kann es daran liegen, daß die Lieferantendatei ca. 83.000 Zeilen, also Datensätze hat?

Das könnte nur ein Problem sein, wenn intern awk auf mawk verlinkt ist. Damit habe ich auch schon Probleme gehabt.

Probier es einfach aus, was awk --version ausgibt. Wenn sich Gnu awk meldet, ist alles in Ordnung.
Wenn nicht, brauchst Du nur gawk nachzuinstallieren.

LG,

track

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

Ja, das sollte in Ordnung sein, es kommt:

GNU Awk 3.1.7

Hm ..., da muß ich mich wohl herantasten, um das Problem zu lokalisieren.

Mal gespannt, auf was für ein Ergebnis ich dabei komme.

Außer, Du hast einen Vorschlag?

Grüße Nobuddy

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Ein anderer sehr beliebter Fehler sind versteckte Leerzeichen. Gerade wenn man TABs als Trenner hat, sieht man die nicht.

Probier mal:

sed -n  's/ /⨆/p'  LISTEGRUND_HERSTELLER.txt  |  grep "⨆"

dann zeigt er die Leerzeichen an.
(edit: die Leerzeichen werden vorher durch ein seltenes Symbol ersetzt. Dann wird dies Symbol rot markiert.)

track

Nobuddy

(Themenstarter)
Avatar von Nobuddy

Anmeldungsdatum:
2. September 2005

Beiträge: 6990

Wohnort: 29614 Soltau

track, mit den versteckten Leerzeichen, hast Du ins Schwarze getroffen.

Die LISTEGRUND_HERSTELLER.txt ist davon nicht betroffen, aber dafür die Lieferantenlisten.

Hier mal ein kleiner Auszug

120	26212868	DC⨆COLOUR PRINTING A4160G WS 250BL	DC COLOUR PRINTING A4160G WS 250BL 	DATACOPY	019501610001	PAK		2						5					7391649731831	0210	0210	103		LAGER
120	26212879	HP⨆OFFICE A4 80G WEIß 500BL	HP OFFICE A4 80G WEIß 500BL 	HEWLETT-PACKARD	CHP110	PAK		2						5					4011211000051	0210	0210	107		LAGER

Nach jedem ersten Wort in der Spalte "Benenung", ist dieses Zeichen vorhanden.

Bin bei der Suche im Forum //forum.ubuntuusers.de/topic/geschuetzte-leerzeichen/?highlight=versteckte+leerzeichen#post-2123421: darauf gestoßen. Ist zwar sehr aufschlussreich, aber eine Lösung konnte ich nicht finden.

Beim Googeln habe ich gelesen, daß geschützte Leerzeichen, mit einem Backslash voran definiert werden.

Ich habe dann mal diese versucht

1
sed 's/\[ ]/ /g' "$zielpool/liste.txt" > "$zielpool/liste0.txt"

, leider ist das Ergebnis unverändert.

Vielleicht hast Du da eine Idee?

Grüße Nobuddy

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Nobuddy schrieb:

... Nach jedem ersten Wort in der Spalte "Benenung", ist dieses Zeichen vorhanden.

Aber das ist doch kein Problem ...?

Denn Du wertest mit Deinem Filter doch nur das Feld "Hersteller" aus, so wie ich Deine Frage oben verstanden habe.
Klar, dass in der Produktbezeichnung Leerzeichen vorkommen, und meinetwegen auch am Ende von dem Feld.

Das interessiert doch überhaupt nicht. Tückisch wäre z.B. sowas: "HEWLETT-PACKARD " - aber das kommt ja gar nicht vor.
Also brauchst du Dich um diese Leerzeichen gar nicht zu kümmern.

Deine Frage oben war doch: Warum funktioniert mein awk-Skript mit der Probe-Herstellerliste "h.txt" aber nicht mit der Original-Herstellerliste ?

Um darauf eine Antwort zu finden, muss man definitiv diese beiden Listen vergleichen.
Was ist bei der Original-Liste anders ? - Wenn da keine drin Leerzeichen sind, (wo sie nicht hin gehören) gibt es dann vielleicht andere "giftige" Zeichen ?

Probier mal it einem Mini-Skript, ob awk die beiden Felder sauber liest:

awk 'BEGIN{FS="\t";OFS="\t"} {print $1, $2}'  "orignalHerstellerDatei.txt"  >  "originalHerstellerDatei.test"
diff "orignalHerstellerDatei.txt" "originalHerstellerDatei.test"

Findet das diff Unterschiede ? - die müsste man sich dann mal näher angucken.

track

Antworten |