mikefield
Goto Top

per Batch Datenbank Export weiter bearbeiten

Habe einen Datenbank Export, von dem ich diverse Spalten und Zeilen mit einem bestimmten Wert benötige

Hallo!
Habe hier einen Datenbank Export von dem ich die Spalten "FIRSTNAME","LASTNAME","LOGINNAME", benötige.
Dieses aber nur wo in der Spalte "DELETEDFLAG", eine 0 steht. Habe schon verschiedenes versucht, komme aber nicht weiter.
Das Ergebnis soll in einer neuen Datei gespeichert werden, die Werte ohne Hochkommata und getrennt mit TAB.
Anbei ein Auszug aus dem Export:

"FIRSTNAME","LASTNAME","MIDDLENAME","FULLNAME","LOGINNAME","DOMAIN","AGENTGROUP","MANAGER_NAME","PREFERREDNAME","TITLE","PASSWORD","PKEY","DISABLELOGINFLAG","HISTORY","EMPLOYEEID","LOCATION","ORGANIZATION_KEY","SOUNDEX","WEBPAGE","MANAGER_KEY","COMMUNICATEPREF","ELECTRONSIGNATURE","FULFILLMENTLIMIT","MANAGERFLAG","NOTES","VOICECONFIG","ROLE_ADMINISTRATOR","ROLE_SUPERVISOR","ROLE_AGENT","ROLE_CLERK","ROLE_POSTMASTER","ROLE_OPERATOR","DELETEDFLAG","AUTOAGENTFLAG","TASKLOAD","TASKCEILING","CHANGEPASSWORDFLAG","PREFIXNAME","SUFFIXNAME","SALUTATION","ROLE_SUPPORT","PHONE","EMAIL","SITE","DATECREATED","DATEMODIFIED","CANPANIC","DOAVAIL","DOWRAPUP","OFFLINEDELIVERY","SENIORITY","ADDRESSABLEFLAG","DISPLAYNAME","EXTERNALFLAG","ADVOCATEFLAG","OUTOFOFFICEFLAG","ROLE_CA_ADMIN","FAILEDLOGINCOUNT","LASTLOGINFAILDATE","LASTLOGINDATE","CHANGEPASSWORDDATE","SITE_KEY","LRMID_KEY","LINKGROUP_KEY","SERVERPROCESS_UUID",  
"Adam","Admin","","Admin, Adam","Admin","User1","","","Adam  Admin","","E2:19b36c440d03c671d32ff6c23eb46251","100001","0","286","","","","A355A350","","","0","","0","","","{0,1,{"autoloadimp","true"}}","1","0","0","0","0","0","0","0","1","1","0","","","","0","","","","","21-Apr-2009 07:02:53 AM","Y","Y","Y","1","0","0","Admin, Adam","0","0","0","0","0","19-Apr-2009 07:31:00 PM","21-Apr-2009 07:02:53 AM","10-Sep-2008 12:00:00 AM","1","","","",  
"website","server","","server, website","website","Website","","","website","","E2:49deb4c2879b7cbaaeb02927caed4590","100002","1","290","","","","S616W123","","","0","","0","","","","0","0","0","0","0","1","0","0","1","1","0","","","","0","","","","","20-Apr-2009 10:17:03 AM","Y","Y","Y","1","0","0","server, website","0","0","0","0","0","20-Apr-2009 10:17:03 AM","19-Apr-2009 07:03:24 PM","08-Dez-2008 12:00:00 AM","1","","","",  
"icmbridge","server","","server, icmbridge","icmbridge","Web","","","icmbridge","","E2:fb45ccd74620fc0608766c49078c8b50","100003","0","289","","","","S616I251","","","0","","0","","","","0","0","0","0","0","1","0","0","1","1","0","","","","0","","","","","19-Apr-2009 07:00:49 PM","Y","Y","Y","1","0","0","server, icmbridge","0","0","0","0","0","","19-Apr-2009 07:00:49 PM","","1","","","",  
"dcobridge1","server","","server, dcobridge1","dcobridge1","User1","","","dcobridge1","","E2:fe347ca98361b4b4515339595711fd8f","100005","0","","","","","S616D216","","","0","","0","","","","0","0","1","0","0","0","0","0","0","0","0","","","","0","","","","","29-Sep-2008 08:33:21 AM","Y","Y","Y","1","0","0","dcobridge1 server","0","0","0","0","3","29-Sep-2008 08:33:21 AM","","","1","","","",  
"Hugo","Habicht","","Habicht, Hugo","ub2ch20","User1","","","Hugo","","E2:e10adc3949ba59abbe56e057f20f883e","100006","0","287","v900702","","","H123H200","","","","","","","","","0","0","1","0","0","0","0","0","1","1","0","","","","0","","","","","13-Sep-2007 08:30:24 PM","Y","Y","Y","1","0","0","Habicht, Hugo","0","0","0","0","0","19-Apr-2007 12:09:55 PM","13-Sep-2007 08:30:24 PM","05-Apr-2007 12:00:00 AM","1","","","",  

Ich hoffe Ihr könnt mir helfen!

mf

Content-Key: 114382

Url: https://administrator.de/contentid/114382

Printed on: April 23, 2024 at 06:04 o'clock

Member: bastla
bastla Apr 21, 2009 at 21:03:39 (UTC)
Goto Top
Hallo Mikefield!

Für einen Batch sind die Daten etwas sehr unhandlich (zu viele Felder), daher eher ein VBScript:
Ein = "D:\Exportdtatei.txt"  
Aus = "D:\NeueDatei.txt"  

Set fso = CreateObject("Scripting.FileSystemObject")  
Daten = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)

Set A = fso.CreateTextFile(Aus)
For i = 0 To UBound(Daten)
    Satz = Split(Daten(i), """")  
    If UBound(Satz) >= 65 Then : If Satz(65) = "0" Then A.WriteLine Satz(1) & vbTab & Satz(3) & vbTab & Satz(9)  
Next
A.Close
[Edit] Art der Zerlegung geändert, da VBS auch unter Anführungszeichen stehende Kommata als Trennzeichen interpretiert; wegen der Doppelzählung der Anführungszeichen ist der Array-Index der Felder nach der Formel "Feldnummer * 2 - 1" zu ermitteln [/Edit]

Grüße
bastla
Mitglied: 77559
77559 Apr 21, 2009 at 21:13:38 (UTC)
Goto Top
Hallo MikeField,

Das geht zwar mit dem folgenden Batch, aber andere Sprachen/Tools gawk z.Bsp. sind besser geeignet.

Wenn du eine Erläuterung der Befehle brauchst, melden.

::StripDeleted.cmd:::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
set DBEx=f:\test\2\DB-Export.csv
set /P Header=<%DBEx%
Call :Process %Header%
for /F "skip=1 delims=" %%A in (%DBEx%) do Call :Process %%A  
goto :Eof
:Process
shift /3
shift /3
for /l %%B in (1 1 27) do shift /4
if %1 NEQ "FIRSTNAME" IF %4 NEQ "0" goto :EOF  
echo %~1	%~2	%~3	%~4

Ich weiß nicht ob die TAB Zeichen in der letzten Zeile den Transportweg überstehen, sonst musst du sie in deinem Editor erneuern.
Wenn die Ausgabe ok erscheint kannst du in der letzten Zeile noch eine Umleitung anhängen >>Ausgabe.txt

Gruß
LotPings
Mitglied: 76109
76109 Apr 22, 2009 at 09:51:21 (UTC)
Goto Top
Hallo Mikefield,

Meine Frage wäre, ob Du den Datenbank-Export selber erstellst und ob es sich um eine Access-Datenbank-Datei handelt?
Wenn ja, wird die Datenbank ständig neu überschrieben oder nur geändert und hat sie ein Passwort, das Dir bekannt ist?

Gruß Dieter
Member: Mikefield
Mikefield Apr 22, 2009 at 14:35:10 (UTC)
Goto Top
So, erst einmal Danke an alle! Die Verarbeitung funktioniert tadellos!
Habe auch schon ein wenig drum herum gebaut, wie Lastname zuerst und die Sortierung danach.

@bastla, da ich das Ergebnis noch ein wenig "tunen" möchte, hilft mir VBS nicht wirklich weiter, da ich da gar nichts mehr verstehe. face-sad Trotzdem vielen Dank! face-smile

@76109: Es ist eine Oracle Datenbank und den Export mache ich manuell. Sie wird IMHO nur geändert und nicht überschrieben.

@77559: Es ist ein wenig ungewöhnlich was Du da erstellt hast, und ich verstehe es nicht wirklich. Kannst Du die Zeilen mal kommentieren? Was mich wundert, ist, daß dieser :Process doppelt aufgerufen wird. Einmal nach dem set /p und dann noch einmal in der For /F Schleife. Was wird mit dem set /p eigentlich wirklich bezweckt?

Was wird mit 2x shift /3 geschoben? Hätte das nicht auch ein shift /6 gemacht? Ahh, habe mal shift /? gemacht. Kann es sein, das Du damit "Middlename und "Fullname" verschiebst um dann als %3 den "Loginname" zu erhalten? Und dann mit for /l und shift /4 den "DELETEDFLAG" als %4 erhalten?
Aber was macht dann noch die for /f Schleife?

mf
Member: bastla
bastla Apr 22, 2009 at 15:03:20 (UTC)
Goto Top
Hallo Mikefield!

Wenn schon das VBS-Script nicht helfen konnte, vielleicht ein anderer Beitrag meinerseits ...

Was mich wundert, ist, daß dieser :Process doppelt aufgerufen wird. Einmal nach dem set /p und dann noch einmal in der For /F Schleife. Was wird mit dem set /p eigentlich wirklich bezweckt?
Damit wird die erste Zeile (Kopfzeile mit Spaltenüberschriften) in die Variable %Header% eingelesen - da diese Zeile anders als die folgenden Datensätze behandelt werden muss, wird vorweg das Unterprogramm ":Process" aufgerufen und dort mit dem Vergleich von %1 auf "FIRSTNAME" eine "Spezialbehandlung" dafür vorgenommen.
Kann es sein, das Du damit "Middlename und "Fullname" verschiebst um dann als %3 den "Loginname" zu erhalten?
Das ist das Ziel der Aktion (BTW @77559: sehr elegant face-smile) - "geschoben" wird allerdings der "Loginname" (nämlich nach vorne).
Aber was macht dann noch die for /f Schleife?
Die Schleife in Zeile 6 liest alle Datensätze (ab Zeile 2, daher "skip=1" - die Feldnamen aus Zeile 1 sind ja schon erledigt) aus und übergibt sie einzeln an das Unterprogramm.

HTH
bastla
[Edit] @77559: Sorry, hätte sehen sollen, dass Du ohnehin schon da bist ... [/Edit]
Mitglied: 76109
76109 Apr 22, 2009 at 15:06:59 (UTC)
Goto Top
Hallo Mikefield,

tja, von Oracle habe ich leider keine Ahnung.

In Access hätte man eine Abrage erstellen können, die genau das exportiert, was von Dir benötigt wird.


Gruß Dieter
Mitglied: 77559
77559 Apr 22, 2009 at 15:07:48 (UTC)
Goto Top
Zitat von @Mikefield:
@77559: Es ist ein wenig ungewöhnlich was Du da erstellt hast, und ich verstehe es nicht wirklich. Kannst Du die Zeilen mal kommentieren?
Gerne
Was mich wundert, ist, das dieser :Process doppelt aufgerufen wird. Einmal nach dem set /p und dann noch einmal in der For /F Schleife.
Ich hatte zuerst vor den Header separat zu behandeln, was sich aber während des Schreibens als nicht notwendig erwies.
Zeile 4 und 5 können ersatzlos gestrichen werden. (Dafür muss skip=1 aus dem for /f Befehl entfernt werden)

Was wird mit dem set /p eigentlich wirklich bezweckt?
Siehe set /? face-wink Als Microsoft den Choice Befehl wegließ haben sie das als Ersatz geschaffen. Eine Eingabemöglichkeit in Batchdateien. Wenn man die Eingabeumleitung benutzt um eine Variable aus einer Datei zu füllen wird nur die erste Zeile gelesen und der Rest verworfen.

Was wird mit 2x shift /3 geschoben? Hätte das nicht auch ein shift /6 gemacht? Ahh, habe mal shift /? gemacht. Kann es sein, das Du damit "Middlename und "Fullname" verschiebst um dann als %3 den "Loginname" zu erhalten?
Exakt Shift /3 heißt ja nicht 3 mal shift sondern an dritter Stelle shiften.

Und dann mit for /l und shift /4 den "DELETEDFLAG" als %4 erhalten?
Ja

Aber was macht dann noch die for /f Schleife?
Die liest Zeilenweise die Eingabedatei in %%A (mit allen Anführungszeichen und Kommata) Lies hierzu mindestens 3 mal die Ausgabe von for /? genau durch face-wink
Die Subroutine trennt die übergebenen Argumente an den Kommata auf in %1..%9 um Zugriff auf weitere Argumente zu bekommen muss man sowieso shiften, kann das aber eben auch weiter hinten machen.

Hier nochmal eine gekürzte Version:
::StripDeleted.cmd:::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
set DBEx=f:\test\2\DB-Export.csv
for /F "delims=" %%A in (%DBEx%) do Call :Process %%A  
goto :Eof
:Process
shift /3
shift /3
for /l %%B in (1 1 27) do shift /4
if %1 NEQ "FIRSTNAME" IF %4 NEQ "0" goto :EOF  
echo %~1	%~2	%~3

Gruß
LotPings
Mitglied: 77559
77559 Apr 22, 2009 at 15:21:05 (UTC)
Goto Top
Zitat von @bastla:
Das ist das Ziel der Aktion (BTW @77559: sehr elegant face-smile) - "geschoben" wird allerdings der "Loginname"
So ein Lob von einem Senior Admin [rot-werd]

[Edit] @77559: Sorry, hätte sehen sollen, dass Du ohnehin schon da bist ... [/Edit]
Keine Ursache.

Gruß
LotPings

PS: Welche Emoticons werden von der Forumsoftware eigentlich in Grafiken umgesetzt?
Member: bastla
bastla Apr 22, 2009 at 15:30:48 (UTC)
Goto Top
Hallo LotPings!
So ein Lob von einem Senior Admin [rot-werd]
Ach, lass mal stecken (und "Senior Admin" ist eine reine "Alterserscheinung" face-wink) ...

Das "Lob" ist allerdings sehr ernst gemeint - Deine Lösungen gefallen mir sehr gut und stellen eine Bereicherung für das Forum dar.

Welche Emoticons werden von der Forumsoftware eigentlich in Grafiken umgesetzt?


Grüße
bastla
Member: Mikefield
Mikefield Apr 22, 2009 at 17:36:16 (UTC)
Goto Top
Ok, hab alles verstanden und ist auch garnicht so schwer - hinterher.

Ich habe in die Batch noch etwas Kosmetik eingebaut, zu der ich noch eine Frage habe:
Der Export liegt irgendwo im Netz und die Ausführung dauert sehr lange. Habe noch in Zeile 16 eine Prozessbar eingebaut, die aber etwas zu oft anspringt, nämlich pro Zeile, was bei knapp 1000 Zeilen etwas zu viel ist. Kann ich das jetzt so ändern, daß diese nur bei jeder 10. Zeile reagiert? Mir schwebt da was mit set Counter= usw. vor, aber gibts da nicht was eleganteres mit einer zusätzlichen for Schleife? Ein Schrittwert von -10 geht ja leider nicht. face-sad

@echo off & setlocal 

:Global
set "Day=%date:~0,2%"  
set "Mon=%date:~3,2%"  
set "Year=%date:~6,4%"  
set "Datum=%Year%%Mon%%Day%  
Set "DBEx1=repemp.csv"  
set "DBEx2=AIC_Export_%Datum%.xls"  
If Exist %DBEx2% del %DBEx2%

:ProcessCall
Echo Info: Erzeuge  %DBEx2%
for /F "usebackq delims=" %%A in (%DBEx1%) do (  
  call :ProcessLine1 %%A
  for /L %%p IN (1,1,1) DO ((SET /P p= .) < NUL)
)
Echo.
Goto Sort

:ProcessLine1
shift /3
shift /3
for /l %%B in (1 1 27) do shift /4
if %1 NEQ "FIRSTNAME" IF %4 NEQ "0" goto :EOF  
echo %~2	%~1	%~3 >> %DBEx2%
goto :EOF

:Sort
Echo Info: Sortiere %DBEx2%
sort "%DBEx2%" /o "%DBEx2%"  
goto :EOF

mf
Member: bastla
bastla Apr 22, 2009 at 17:54:30 (UTC)
Goto Top
Hallo Mikefield!

Ich würd's auch mit einem Zähler (und Verwendung selbiger als Schalter - erspart "delayedexpansion") machen:
@echo off & setlocal 

:Global
set "Day=%date:~0,2%"  
set "Mon=%date:~3,2%"  
set "Year=%date:~6,4%"  
set "Datum=%Year%%Mon%%Day%  
Set "DBEx1=repemp.csv"  
set "DBEx2=AIC_Export_%Datum%.xls"  
If Exist %DBEx2% del %DBEx2%
set counter=0

:ProcessCall
Echo Info: Erzeuge  %DBEx2%
for /F "usebackq delims=" %%A in (%DBEx1%) do (  
  call :ProcessLine1 %%A
  if not defined counter set /p p=.<nul
)
Echo.
Goto Sort

:ProcessLine1
shift /3
shift /3
for /l %%B in (1 1 27) do shift /4
if %1 NEQ "FIRSTNAME" IF %4 NEQ "0" goto :EOF  
echo %~2	%~1	%~3 >> %DBEx2%

set /a counter+=1
if %counter%==10 set "counter="  
goto :EOF

:Sort
Echo Info: Sortiere %DBEx2%
sort "%DBEx2%" /o "%DBEx2%"  
goto :EOF
Grüße
bastla
Mitglied: 77559
77559 Apr 22, 2009 at 18:17:56 (UTC)
Goto Top
Counter geht, aber besser in in die Subroutine packen.

Die ganze shifterei ist zwar elegant aber nicht sehr effizient.
Pro Zeile werden ja sehr viele Felder eliminiert.

Der Sort Teil kann eigentlich ohne Springen direkt unter die for Schleife.

Der set /A Befehl kann auch, was nicht (gut) dokumentiert ist, mehrere math. Operationen in einem Rutsch ausführen - wenn in Anführungszeichen gesetzt auch ohne Variablen in störende Prozentzeichen zu packen.

@echo off & setlocal 
:Global
set "Day=%date:~0,2%"  
set "Mon=%date:~3,2%"  
set "Year=%date:~6,4%"  
set "Datum=%Year%%Mon%%Day%  
Set "DBEx1=repemp.csv"  
set "DBEx2=AIC_Export_%Datum%.xls"  
If Exist %DBEx2% del %DBEx2%

Echo Info: Erzeuge  %DBEx2%
for /F "usebackq delims=" %%A in (%DBEx1%) do call :Process %%A  

Echo.
Echo %cnt% Zeilen verarbeitet, davon %cntvalid% Valide
Echo Info: Sortiere %DBEx2%
sort "%DBEx2%" /o "%DBEx2%"  
goto :EOF

:Process
set /A "cnt+=1,Rest=cnt %% 10"&if %Rest%. EQU 0. set /P X=.<NUL  
shift /3
shift /3
for /l %%B in (1 1 27) do shift /4
if %1 NEQ "FIRSTNAME" IF %4 NEQ "0" goto :EOF  
echo %~2	%~1	%~3 >> %DBEx2%
set /A "cntvalid+=1  
Member: bastla
bastla Apr 22, 2009 at 18:28:03 (UTC)
Goto Top
@77559
Der set /A Befehl kann auch, was nicht (gut) dokumentiert ist, mehrere math. Operationen in einem Rutsch ausführen - wenn in Anführungszeichen gesetzt auch ohne Variablen in störende Prozentzeichen zu packen.
... wobei (was eigentlich gar nicht dokumentiert ist face-wink) noch nicht einmal die Anführungszeichen erforderlich sind (und auch die Leerzeichen vor und nach dem Modulo-Operator %% brauchts nicht).
Worin siehst Du übrigens den Vorteil von
%Rest%. EQU 0.
gegenüber
%Rest%==0

Grüße
bastla
Mitglied: 77559
77559 Apr 22, 2009 at 19:07:11 (UTC)
Goto Top
Zitat von @bastla:
... wobei (was eigentlich gar nicht dokumentiert ist face-wink) noch nicht einmal die Anführungszeichen erforderlich sind (und auch die Leerzeichen vor und nach dem Modulo-Operator %% brauchts nicht).
Stimmt wohl, aber da ich öfter mit den binären shift Operatoren >> und << gearbeitet habe, die die Anführungszeichen haben müssen, habe ich es mir angewöhnt.

Worin siehst Du übrigens den Vorteil von
%Rest%. EQU 0.
> 
gegenüber
%Rest%==0
> 
Ebenfalls reine Angewohnheit/Vorliebe: Editoren mit Syntax-Highlighting heben IMO die alphabetischen Vergleichsoperatoren besser ab, der Punkt um möglichst niemals eine Variable, die leer sein könnte, allein stehen zu haben.

Gruß
LotPings
Member: Mikefield
Mikefield Apr 22, 2009 at 19:52:42 (UTC)
Goto Top
Ihr mit Eurem Fachgesimpel, da soll noch einer mitkommen! face-smile
Freut mich, Euch in ein anregendes Gespräch verwickelt zu haben.

Aber könnt Ihr mir bitte diese set /a Zeile innerhalb der Kommata erklären? Kann man anstatt cnt+=1 auch cnt=+1 verwenden?
Also "cnt" und "Rest" sind in diesem Fall Variablen. Aber das Komma ist ohne Leerzeichen. Muß das so sein? Rest=cnt %% 50 was wird hier wie verarbeitet? Das folgende If vergleicht den "Rest" Parameter, aber wann wird der auf 0 (eigentlich 1) gesetzt?

mf
Mitglied: 77559
77559 Apr 22, 2009 at 20:06:37 (UTC)
Goto Top
Zitat von @Mikefield:
Ihr mit Eurem Fachgesimpel, da soll noch einer mitkommen! face-smile
Das kommt schon noch face-wink
Freut mich, Euch in ein anregendes Gespräch verwickelt zu haben.
Ich bin zwar erst seit einer Woche hier dabei; aber wir begegnen uns immer wieder face-smile

Aber könnt Ihr mir bitte diese set /a Zeile innerhalb der Kommata erklären? Kann man anstatt cnt+=1 auch cnt=+1 verwenden?
Das hat aber dann die normale Bedeutung eines Vorzeichens.

Also "cnt" und "Rest" sind in diesem Fall Variablen. Aber das Komma ist ohne Leerzeichen. Muß das so sein?
Das Komma trennt zwei unterschiedliche Berechnungen. Rechnen mit set /A ist immer Integer-Rechnen. Ein Dezimalkomma gibt es daher nicht.

Rest=cnt %% 50 was wird hier wie verarbeitet? Das folgende If vergleicht den "Rest" Parameter, aber wann wird der auf 0 (eigentlich 1) gesetzt?
Das ist die Modulo = Divisionsrest-Funktion

Immer wenn die Division durch 10 Rest 0 ergibt wird also ein Punkt ausgegeben.
Gruß
LotPings
Member: Mikefield
Mikefield Apr 22, 2009 at 20:14:43 (UTC)
Goto Top
Ah ja, Super wie das so alles in Batch funktioniert! face-smile
Eins habe ich noch. Die Berechnung der Zeilen gibt folgendes aus:
1494 Zeilen verarbeitet, davon 1371 Valide
Aber es sind 944 zu 863 wo kommt die Fehlkalkulation zustande?

mf
Mitglied: 77559
77559 Apr 22, 2009 at 20:26:12 (UTC)
Goto Top
Zitat von @Mikefield:
Eins habe ich noch. Die Berechnung der Zeilen gibt folgendes aus: 1494 Zeilen verarbeitet, davon 1371 Valide
Aber es sind 944 zu 863 wo kommt die Fehlkalkulation zustande?

Die Variablen sind nicht initialisiert, setz mal testhalber
set cnt=0
set cntvalid=0

Mit an den Anfang. Ansonsten sehe ich keine Fehler.
Member: Mikefield
Mikefield Apr 22, 2009 at 20:48:07 (UTC)
Goto Top
Habe ich gerade gemacht, hatte die selbe Idee. Vorher aber mit Echo abgefragt: 551 und 508, jetzt klappt auch das!
Vielen Dank und angenehme Nachtruhe! face-smile

mf