linm2002
Goto Top

Mehrere CSV Dateien zusammenfügen, nicht hintereinander, sondern parallel

Hallo,

ich möchte gerne mehrere CSV Dateien per Batch zusammenfügen, aber nicht hintereinander, sondern parallel, hier ein Beispiel.
Datei 1:
Datum; Spalte 1; Spalte 2; ...; Spalte n
01.01.2011 00:00; 111; 222; ... ; nnn
02.01.2011 00:00; 222; 333; ... ; mmm

Datei 2:
Datum; Spalte 1; Spalte 2; ...; Spalte x
01.01.2011 00:00; 123; 234; ... ; yyy
02.01.2011 00:00; 234; 345; ... ; zzz
.
.
.
Datei n:
01.01.2011 00:00; ...; ...; ...
02.01.2011 00:00; ...; ...; ...

Daraus soll das werden:
Datum; Spalte 1; Spalte 2; ...; Spalte n; Spalte n+1; ... ; Spalte n+x; ...
01.01.2011 00:00; 111; 222; ... ; nnn; 123; 234; ... ; yyy; ...
02.01.2011 00:00; 222; 333; ... ; mmm; 234; 345; ... ; zzz; ...

hab lange nach der Lösung gesucht, leider nichts passendes gefunden.

Für eure Tipps wäre ich sehr dankbar.

Schöne Grüße
Min

Content-Key: 169591

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

Ausgedruckt am: 29.03.2024 um 01:03 Uhr

Mitglied: Friemler
Friemler 12.07.2011 um 18:59:03 Uhr
Goto Top
Hallo Min,

teste mal das hier:
Const ForReading = 1
Const ForWriting = 2


'Anzahl der Parameter prüfen  
If WScript.Arguments.Count > 2 Then
  Set objFSO     = CreateObject("Scripting.FileSystemObject")  
  Set objOutFile = objFSO.OpenTextFile(WSCript.Arguments(0), ForWriting, True)

  'Zähler für die schon verarbeiteten Zeilen pro Datei  
  intSkipLines = 0

  'Wiederholen, bis alle Zeilen jeder Datei verarbeitet wurden  
  Do
    'Alle Eingabedateien nacheinander öffnen  
    For intFileCntr = 1 To WScript.Arguments.Count - 1
      'Nachsehen, ob es zum aktuelllen Dateinamen auch eine Datei auf der Platte gibt  
      'Wenn nicht, Abbruch  
      If Not objFSO.FileExists(WScript.Arguments(intFileCntr)) Then
        WScript.Echo "Datei " & WScript.Arguments(intFileCntr) & " nicht gefunden."  
        Exit Do
      End If

      'Datei zum Lesen öffnen  
      Set objInFile = objFSO.OpenTextFile(WScript.Arguments(intFileCntr), ForReading, False)

      'So viele Zeilen überspringen wie bisher schon verarbeitet wurden  
      For I = 1 To intSkipLines
        objInFile.SkipLine
      Next

      'Wenn das Dateiende erreicht ist, Abbruch  
      '=> Alle Dateien müssen die gleiche Anzahl Zeilen haben  
      If objInFile.AtEndOfStream Then Exit Do

      'Aktuelle Zeile einlesen und anhand des Semikolons in Felder  
      'zerlegen und die einzelnen Felder in einem Array speichern  
      arrLine = Split(objInFile.ReadLine, ";")  

      'Die erste Spalte der Ausgabedatei enthält die Elemente  
      'der ersten Spalte der 1. Eingabedatei  
      'Bei allen anderen Eingabedateien wird die erste Spalte überlesen  
      If intFileCntr = 1 Then objOutFile.Write arrLine(0)

      'Die übrigen Spalten der Eingabedatei in die Ausgabedatei schreiben  
      'mit einem Semikolon als Trennzeichen  
      For I = 1 To UBound(arrLine)
        objOutFile.Write ";" & arrLine(I)  
      Next

      'Eingabedatei schließen  
      objInFile.Close
    Next

    'Zeilenumbruch in Ausgabedatei schreiben  
    objOutFile.Write vbCRLF

    'Anzahl zu überspringender Zeilen für den nächsten Durchlauf um 1 erhöhen  
    intSkipLines = intSkipLines + 1
  Loop

  'Ausgabedatei schließen  
  objOutFile.Close
Else
  'Zu wenig Parameter => Fehlermeldung ausgeben  
  WScript.Echo "Geben Sie mindestens eine Zieldatei und zwei Quelldateien als Parameter an."  
End If

Aufruf:
cscript /nologo MergeCSV.vbs "OutFile" "InFile1" "InFile2" "InFile3" ... "InFileN"

Alle Eingabedateien müssen die gleiche Anzahl Zeilen haben.

Gruß
Friemler
Mitglied: pieh-ejdsch
pieh-ejdsch 12.07.2011 um 19:13:33 Uhr
Goto Top
moin Min,

was Leichtes nach Zeilennummern

@echo off&setlocal
set "File1=Datei 1"  
set "Neu=Alles.csv"  
type nul>"%neu%"  
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%File1%"') do (set "Line=%%j"  
  for %%a in (
    "Datei 2"  
    "Datei n"  
    WriteIn:
  ) do (if not "%%~a" == "WriteIn:" for /f "tokens=1* delims=;" %%b in ('findstr /n "^" "%%~a"^|findstr /b "%%i:"') do set "LineB=%%c"  
    setlocal enabledelayedexpansion
    if not "%%~a" == "WriteIn:" ( for /f "delims=" %%d in ("!Line!;!LineB!") do endlocal& set "Line=%%d"  
    ) else ( >>"%neu%" echo\!Line!  
      endlocal
)  )  )

ungetestet einen Vergleich nachgezogen
[Edit]
to late - da war Friemler wieder schneller


Gruß Phil
Mitglied: linm2002
linm2002 12.07.2011 um 21:22:37 Uhr
Goto Top
Hallo Friemler,

erstmal vielen Dank für die schnelle Antwort.

Ich bin hier ein absoluter Anfänger, und hab deine Code nicht 100% verstanden. Kannst du mir genau sagen, was ich machen soll?

Ich habe jetzt zum Test 3 csv-Dateien abgelegt (c:\test\test1.csv; test2.csv; test3.csv), die gleiche Anzahl der Zeilen haben. Deine Code habe ich als MergeCSV.vbs und zum Aufruf habe ich

cscript /nologo MergeCSV.vbs "OutFile.csv" "test1.csv" "test2.csv" "test3.csv"

als test.bat Datei in den selben Ordner gespeichert.

Doppelklicken test.bat, hat nichts passiert.face-sad

Gruß
Min
Mitglied: linm2002
linm2002 12.07.2011 um 21:33:54 Uhr
Goto Top
Hallo Phil,

vielen Dank erstmal face-smile

deine Code habe ich wie folgenden angepasst und als test.bat gespeichert:

@echo off&setlocal
set "File1=test1.csv"  
set "Neu=Alles.csv"  
type nul>"%neu%"  
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%File1%"') do (set "Line=%%j"  
  for %%a in (
    "test2.csv"  
    "test3.csv"  
    WriteIn:
  ) do (if not "%%~a" == "WriteIn:" for /f "tokens=1* delims=;" %%b in ('findstr /n "^" "%%~a"^|findstr /b "%%i:"') do set "LineB=%%c"  
    setlocal enabledelayedexpansion
    if not "%%~a" == "WriteIn:" ( for /f "delims=" %%d in ("!Line!;!LineB!") do endlocal& set "Line=%%d"  
    ) else ( >>"%neu%" echo\!Line!  
      endlocal
)  )  )

leider hat es nicht geklappt. Habe ich was falsch gemacht?

Gruß
Min
Mitglied: Friemler
Friemler 12.07.2011 um 22:50:32 Uhr
Goto Top
Hallo Min,

dann müsste jetzt eigentlich eine Datei namens OutFile.csv im Verzeichnis angelegt worden sein. Eine Ausgabe im Sinne von "Dateien wurden gemergt" o.ä erfolgt nicht.

Du könntest aber die Test.bat um eine Zeile mit dem Befehl PAUSE ergänzen, dann schließt sich das Konsolenfenster nicht sofort wieder und Du kannst evtl. auftauchende Fehlermeldungen lesen.

Bei mir funktioniert es auf jeden Fall.

Gruß
Friemler


[EDIT]
Da Du mit Phils Code auch kein Glück hattest - was steht denn in den CSV-Dateien drin?
[/EDIT]
Mitglied: pieh-ejdsch
pieh-ejdsch 12.07.2011 um 22:52:18 Uhr
Goto Top
liegt wird Die Test bat im gleichen Verzeichnis wie die *.CSV getartet, dann sollte es funktionieren.

sonst gibst Du die Kompletten Pfade mit an oder Wechselst zu beginn des Batches mit
pushD "D:\Das Verzeichnis mit den CSVs"
ins Verzeichnis und zum Ende des Batches mit
popD
wieder heraus.

auf der CMD-Line testen und Meldungen lesen - sonst mit echo on laufen lassen.
Bei mir tat es so wie es sollte.

Friemlers code ist eine VBS kein Batch

@Friemler schöne Doku - ich versuch mich auch grad ein bissel in VBS Einzulesen

Gruß Phil
Mitglied: Friemler
Friemler 12.07.2011 um 23:09:34 Uhr
Goto Top
Hi Phil,

Zitat von @pieh-ejdsch:
ich versuch mich auch grad ein bissel in VBS Einzulesen

wenn Du's nicht schon kennst - suche mit Google mal nach "script56.chm". Das ist eine Sprachreferenz zu VBScript und JScript. Damit findet man schnell einen Einstieg.

In manchen Fällen geht mir das Batchgeraffel mächtig auf den Senkel, da das coden in Batchscript dem durchschlängeln durch ein Minenfeld gleicht. In VBS kann man sich doch mehr auf den eigentlichen Algorithmus konzentrieren, ohne ständig irgendwelche Unzulänglichkeiten umschiffen zu müssen.

Jedes Ding halt für den Zweck, für den es am besten geeignet ist. Textdateien mit beliebigem Inhalt zu verarbeiten ist in Batchscript immer eine Lotterie.

Gruß
Friemler
Mitglied: Biber
Biber 12.07.2011 um 23:45:48 Uhr
Goto Top
[OT]
Moin Friemler,

Zitat von @Friemler:
Textdateien mit beliebigem Inhalt zu verarbeiten ist in Batchscript immer eine Lotterie.
Ja, und ergänzend dazu...
Unabhängig vom verwendeten Werkzeug sollte nie die Frage vergessen werden, ob denn überhaupt eine Nachbearbeitung der beste und der einzige Plan ist.
Dieser lieb- und ideenlos von irgendwelchen Azubis in ein wehrloses Logfile geleierte Output, der auch diesem Thread auf ein halbwegs zumutbares Lesbarkeitsniveau hochformatiert wird ...
--- Ja hey!
- Entweder ich setze an der Quelle an, da wo die Daten geschrieben werden und bitte um Anpassung
- oder ich wechsele das Tool, weil offensichtlich ungeeignet oder ich schreibe ein eigenes.

Diesen immer wiederkehrenden Unsinn mit "Ich brauche aus einer völlig verqueren Textsalatdatei immer nur das achte Wort aus Zeile 144 und die darauffolgenden 12 Zeichen, aber mit führenden Nullen"....

--> das kann doch nicht wahr sein, dass bei der Erzeugung der Daten huschi-huschi in 12sec irgendwas rausgetrümmert und dankend angenommen wird und danach ohne einen einzigen Seufzer tagelang mit Batch, VBS und C# aus Zeichenbrei Informationen destilliert werden sollen.

Grüße
Biber
[/OT]
Mitglied: linm2002
linm2002 13.07.2011 um 00:06:35 Uhr
Goto Top
Hallo Friemler,

in den csv-Dateien steht:

Datum;Z1;Z2;Z3
01.01.2011 00:00;1;2;3
02.01.2011 00:00;2;3;4

alle 3 Test csv-Dateien sind identisch. Wie Du gesagt hast, habe ich die Datei OutFile.csv im Verzeichnis angelegt und die Test.bat mit der Zeile PAUSE ergänzt. Es sieht jetzt wie folgenden aus:

cscript /nologo MergeCSV.vbs "OutFile.csv" "test1.csv" "test2.csv" "test3.csv"  
PAUSE

Trotzdem schließt sich das Konsolenfenster sofort wieder und die Daten sind nicht in OutFile.csv zusammengefügt. Bin echt ratlos face-sad

Gruß
Min
Mitglied: linm2002
linm2002 13.07.2011 um 00:20:40 Uhr
Goto Top
Hallo Phil,

die Code sind jetzt wie folgenden angepasst:

echo on & setlocal
pushd "d:\Test\"  
set "File1=test1.csv"  
set "Neu=Alles.csv"  
type nul>"%Neu%"  
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%File1%"') do (set "Line=%%j"  
	for %%a in (
		"test2.csv"  
		"test3.csv"  
    		WriteIn:
) do (if not "%%~a" == "WriteIn:" for /f "tokens=1* delims=;" %%b in ('findstr /n "^" "%%~a"^|findstr /b "%%i:"') do set "LineB=%%c"    
		setlocal enabledelayedexpansion
		if not "%%~a" == "WriteIn:" ( for /f "delims=" %%d in ("!Line!;!LineB!") do endlocal& set "Line=%%d"    
		) else ( >>"%neu%" echo\!Line!   
	endlocal
)  )  )
popd

Es hat aber nicht funktioniert. Das Konsolenfenster schließt sich nach wie vor sofort wieder. Das verstehe ich echt nicht ...

PS: alle csv-Dateienn und bat-Datei sind in einem Ordner abgelegt.

Gruß
Min
Mitglied: Friemler
Friemler 13.07.2011 um 00:35:13 Uhr
Goto Top
Hallo Min,

also das Konsolenfenster sollte sich nicht wieder direkt schließen, dafür ist ja der PAUSE-Befehl. Mir ist jetzt auch kein Szenario eingefallen unter dem das passieren könnte.

Starte doch bitte über das Startmenü erstmal ein Konsolenfenster (CMD.exe). Wechsele dann mit CD in dein Test-Verzeichnis und starte erst jetzt die Test.bat. Dann müsste auf jeden Fall die Befehlszeile aus dem Batchfile ausgegeben werden und evtl. irgendeine Fehlermeldung erscheinen.

BTW: Die Datei OutFile.csv brauchst Du nicht anzulegen. Die wird vom Script als Ausgabedatei erzeugt. Der erste Dateiname in der Befehlszeile nach dem Scriptnamen bezeichnet die Ausgabedatei, alle weiteren Dateinamen stehen für die Namen von Eingabedateien.

Gruß
Friemler


[EDIT]
Mir ist doch noch ein Szenario eingefallen, unter dem sich das Konsolenfenster direkt schließt: Du hast das Batchscript in Unicode-Codierung gespeichert. Falls Du es mit Notepad erstellt hast, lade das Batchfile in Notepad und gehe dann auf Menü Datei->Speichern unter.... Wenn dort unten in der Mitte im Feld Codierung Unicode oder UTF-8 steht, klappe die Combobox auf und wähle ANSI aus. Dann speichern. Bei den anderen Dateien bitte auch prüfen.
[/EDIT]
Mitglied: pieh-ejdsch
pieh-ejdsch 13.07.2011 um 01:04:13 Uhr
Goto Top
Öffne erst eine CMD und ziehe den Batch dahinein, dann Enter.
Dann solltest Du alles Nachlesen können.
@Friemler die script56.chm hab ich noch nicht komplett durch to much english hab aber noch andere Seiten gefunden. Learning bei doing ist angebracht.

Gruß Phil
Mitglied: Friemler
Friemler 13.07.2011 um 01:08:57 Uhr
Goto Top
Hey Phil,

na, ein Programmierer muss doch Englisch können... face-wink

Aber hier gibt es die Datei auch auf deutsch (Link ist unter der fetten Überschrift Microsoft Windows Script-Technologien - Hilfe).

Gruß
Friemler
Mitglied: linm2002
linm2002 13.07.2011 um 01:09:52 Uhr
Goto Top
Hallo Friemler,

das ist echt klasse! Genau daran liegt es. Endlich funktioniert.

Nochmal vielen Dank an alle.

Gruß
Min
Mitglied: pieh-ejdsch
pieh-ejdsch 13.07.2011 um 10:21:05 Uhr
Goto Top
Danke Friemler, jetzt versteh ich wenigstens nicht nur die Hälfte.

na, ein Programmierer muss doch Englisch können...
der Urschleim wurde doch auch Eingedeutscht "Hallo Welt!"

Gruß Phil