joker313
Goto Top

Batch zum zusammenfügen von CSV Dateien und dem hinzufügen des Dateinamens

Hallo liebes Forum,

ich habe gesehen, dass hier einige sehr engagierte und fachkundige User unterwegs sind und ich würde mich freuen, wenn man mir bei meinem Problem helfen könnte. face-smile

Ich habe in einem Ordner ziemlich viele csv Dateien und ich möchte diese gesammelt in einer Datei speichern. Das habe ich noch hinbekommen!

Die csv Datei sieht folgender Maßen aus (eine Zeile als Beispiel):

Transaction ID,"Transaction Code","User","Domain","Location","Datum und Uhrzeit","Datum und Uhrzeit","Länge","Rate","Preis","Acces Type","Usage"

Mein Batch, dass diese Dateien zusammenfügt, sieht folgender Maßen aus:


"gesammelt.csv" type nul
for /f "delims=" %%a in ('dir /a-d /b *.csv^|findstr /vic:"gesammelt.cs"') do >>"gesammelt.csv" type "%%~a"


Am Ende entsteht die Datei gesammelt.csv mit allen Zeilen der jeweiligen Dateien. Nun hätte ich aber gerne den Dateinamen der Datei als extra Spalte!

Der Dateiname sieht wie folgt aus:

sess=02cfffc6d6b2868ce833b2dc4c821e85&m=Datum&f=Datei.html&z=1056446&c=1045675.csv

Nun hätte ich gerne in meiner zusammen gefassten Datei die letzten Ziffern (in diesem Fall 1045675) des Dateinamens als Spalte um diese als Indikator zu nutzen zum wem ich das zuordnen muss.

Wäre super, wenn jemand hier eine Lösung parat hätte, mir würde es eine Menge Arbeit ersparen face-smile


Danke im Voraus für die Hilfe!

Grüße

Content-Key: 184077

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

Printed on: April 26, 2024 at 04:04 o'clock

Member: bastla
bastla Apr 25, 2012 at 09:58:51 (UTC)
Goto Top
Hallo Joker313 und willkommen im Forum!

Ungetestet etwa so:
@echo off & setlocal
set "Sammel=gesammelt.csv"  
set "Delim=,"  

>"%Sammel%" type nul  
for /f "delims=" %%a in ('dir /a-d /b *.csv^|findstr /vic:"%Sammel%"') do call :ProcessFile "%%a"  
goto :eof

:ProcessFile
for /f "tokens=6 delims==" %%i in ("%~n1") do set "Datei=%%i"  
(for /f "usebackq eol=§ delims=" %%i in (%1) do (  
    set "Zeile=%%i"  
    setlocal enabledelayedexpansion
    echo !Zeile!%Delim%%Datei%
    endlocal
))>>"%Sammel%"  
goto :eof
Hinweis zu Zeile 11: "§" soll ein Zeichen darstellen, das in der csv-Datei nicht vorkommt; falls sichergestellt ist, dass keine Zeile mit ";" beginnt, kann "eol=§" auch gleich weggelassen werden ...

Grüße
bastla
Mitglied: 106009
106009 Apr 25, 2012 at 10:42:37 (UTC)
Goto Top
Hallo und willkommen im Forum. face-wink

Oder so, etwas kürzer vielleicht?
setlocal enabledelayedexpansion
>"gesammelt.csv" type nul  
for /f "delims=" %%a in ('dir /a-d /b *.csv^|findstr /vic:"gesammelt.cs"') do call :process "%%a"  
goto :eof

:Process
for /f "tokens=6 delims==" %%x in ("%~1") do set number=%%~nx  
for /f "delims=" %%z in ('type "%~1"') do set "zeile=%%z" & @echo %number%,!zeile! >> gesammelt.csv   
goto :eof

Gruß
Member: Skyemugen
Skyemugen Apr 25, 2012 at 10:49:00 (UTC)
Goto Top
Aloha ollidolli,

ähm überlege dir den process-Part der zweiten Schleife lieber noch einmal face-wink

ich weiß ja nicht, ob der TE gefragt hat, dass er nur die letzte Zeile einer .csv haben will ... aber ... Zweifel mit kürzer wird da nix

greetz André
edit: ah, er hat sich's überlegt ...
Member: Joker313
Joker313 Apr 25, 2012 at 11:15:39 (UTC)
Goto Top
Du bist der König!

Tausend Dank!

!!!!

Gruß eines zufriedenden Users!
Member: Joker313
Joker313 Apr 25, 2012 at 11:17:26 (UTC)
Goto Top
Dank dir ebenfalls Ollidolli, wenn ich möchte kann ich auch deins ausprobieren, habe aber eigentlich mit bastlas Lösung gute Erfahrungen sammeln können ;)
Member: bastla
bastla Apr 25, 2012 at 12:25:01 (UTC)
Goto Top
@106009
etwas kürzer vielleicht?
Sicher dann, wenn in den Dateien mindestens ein "!" vorkommt (bei zweien sogar überproportional) ... face-wink

... aber wenn kürzerer Code das Ziel ist, kannst Du auch auf die Verwendung eines Unterprogramms verzichten (und vielleicht doch "gesammelt.csv" in eine Variable packen).

Grüße
bastla
Mitglied: 106009
106009 Apr 25, 2012 at 12:36:22 (UTC)
Goto Top
Hi,

Zitat von @bastla:
... aber wenn kürzerer Code das Ziel ist, kannst Du auch auf die Verwendung eines Unterprogramms verzichten (und vielleicht
doch "gesammelt.csv" in eine Variable packen).

Man kann viel tun, wenn der Tag lang ist. Man kann aber auch den Code so erstellen, dass er sich der Ursprungsversion des TE etwas annähert und dadurch auch ohne zusätzliche Erläuterungen verständlicher wird.
Man kann auch immer alles ganz anders machen. face-smile

Du brauchst dich nicht auf den Schlips getreten zu fühlen, ich hatte nichts gegen deinen Code. face-smile

Gruß
Member: bastla
bastla Apr 25, 2012 at 12:45:01 (UTC)
Goto Top
Hallo ollidolli!
Du brauchst dich nicht auf den Schlips getreten zu fühlen, ich hatte nichts gegen deinen Code. face-smile
Kein Problem face-smile - und der Hinweis war ernst gemeint (Unterprogramme setze ich meist zur "delayedExpansion"-Vermeidung ein - wenn die aber ohnehin im gesamten Batch gelten soll, braucht's das Unterprogramm hier gar nicht):
setlocal enabledelayedexpansion
>"gesammelt.csv" type nul  
for /f "delims=" %%a in ('dir /a-d /b *.csv^|findstr /vic:"gesammelt.cs"') do (  
    for /f "tokens=6 delims==" %%x in ("%%~na") do set number=%%~nx  
    for /f "delims=" %%z in ('type "%%a"') do set "zeile=%%z" & @echo !number!,!zeile!  
)>>gesammelt.csv
Den Namen der Ausgabedatei würde ich aber jedenfalls (wartungssfreundlicher) in eine Variable setzen.
auch ohne zusätzliche Erläuterungen
wäre das abgegangen, wenn der TE auch die Daten beschrieben hätte (was aber vorausgesetzt hätte, dass er über die Besonderheiten hinsichtlich "!" oder ein ";" am Zeilenanfang Bescheid weiß) ...

Grüße
bastla
Mitglied: 106009
106009 Apr 25, 2012 at 12:53:09 (UTC)
Goto Top
Hi, bastla
im Prinzip hast du ja Recht und dagegen ist auch überhaupt nichts einzuwenden. Ich stehe aber auf dem Standpunkt, dass sich die Aufteilung mit einem Unterprogramm sowohl leichter darstellen als auch leichter pflegen lässt als ein Einzeilerwurm.

Und zur Beschreibung der Daten: Mit ziemlicher Wahrscheinlichkeit lässt sich aus den getroffenen Angaben über den Inhalt der Felder schließen, dass sich dort wohl keine "!" verstecken werden, zumindest bin ich davon ausgegangen.

Gruß
Member: bastla
bastla Apr 25, 2012 at 12:57:33 (UTC)
Goto Top
Hallo ollidolli!
zumindest bin ich davon ausgegangen.
Mach ich ja durchaus auch öfter mal - aber im Zweifelsfall kommuniziere ich das dann zur Sicherheit auch ...
Ganz so schlimm (und auch gar nicht einzeilig) wäre aber doch auch die Version ohne Unterprogramm nicht (s.o.) - und um auch mal eine Annahme zu treffen face-wink: Performance dürfte hier nicht unbedingt das Kriterium sein (aber falls doch, wäre das grundsätzlich ein weiteres Argument gegen die Verwendung des Unterprogramms) ...

Grüße
bastla
Mitglied: 106009
106009 Apr 25, 2012 at 13:05:38 (UTC)
Goto Top
Zitat von @bastla:
Ganz so schlimm (und auch gar nicht einzeilig)
Doch. Eingeklammerte Werte werden doch angeblich wie eine Zeile behandelt.
Performance dürfte hier nicht unbedingt das Kriterium sein (aber falls doch, wäre das
grundsätzlich ein weiteres Argument gegen die Verwendung des Unterprogramms) ...

Das vermutest du, ich vermute da auch was: Sehr wahrscheinlich behandelt der Compiler diese "eine Zeile" genauso, als ob sie ein Unterprogramm wäre, nämlich durch call (local-) Label ..... RET
Oder hast du schon mal einen Batchlauf mit einem Debugger beobachtet? Ich schon, aber das ist schon ungefähr ein Jahrzehnt her. face-wink

Aber wollen wir nun wirklich den Thread hier durch Spitzfindigkeiten aufblähen? Der Eine löst es so, der Anderen wählt einen anderen Weg. Beides funktioniert, und das ist doch die Hauptsache. face-wink

Gruß
Member: bastla
bastla Apr 25, 2012 at 13:12:43 (UTC)
Goto Top
Hallo ollidolli!
Eingeklammerte Werte werden doch angeblich wie eine Zeile behandelt.
Vom Interpreter ja - vom Leser / Bearbeiter des Codes eher nicht ...

... ansonsten hat Du recht: lassen wir's gut sein. face-smile

Grüße
bastla