CSV Dateien mit Batch zusammenfügen

leonderprofy

Newbie
Registriert
Feb. 2020
Beiträge
3
Hallo zusammen,

ich möchte in einem Ordner existierende CSV-Dateien nach chronologischer Reihenfolge mittels einer Batch Datei zu einer einzelnen CSV-Datei zusammenfügen.

Die CSV-Dateien sollen nach ihrem Namen sortiert eingefügt werden (nicht nach Änderungsdatum oder Erstellungsdatum).

Die CSV-Dateien sind alle wie folgt durchgehend mit Datum aufsteigend abgelegt: 123456789_data_2019_12_01.csv, 123456789_data_2019_12_02.csv, 123456789_data_2019_12_03.csv,...
Wobei die ersten neun Zahlen sowie "data" am Anfang des Namens pro Ordner identisch sind.

Die einzelnen CSV-Dateien besitzen alle die gleiche Kopfzeile. Die zusammengefügte CSV-Datei soll die Kopfzeile der ersten CSV-Datei behalten und beim Kopieren der weiteren Dateien deren Kopfzeile löschen, sodass eine lückenlose Datei (ohne Leerzeilen, siehe Anhang "gesammelt.csv") entsteht mit nur einer Kopfzeile.

Des Weitern wäre es praktisch, wenn die Batch Datei ohne eine Änderung im Code direkt ausgeführt werden könnte (keine Anpassung von z.B. Pfad, etc. notwendig).

Problem: Ich habe gute Kenntnisse in C++ und Python, jedoch kenne ich mich leider mit Batch Programmierung überhaupt nicht aus.

Durch Recherche im Internet habe ich schon zwei funktionsfähige Dateien (Code A und Code B) gefunden. Beide zusammen erfüllen alle oben beschriebenen Teilfunktionen meiner „Wunschdatei“. Ich schaffe es jedoch nicht diese zu vereinigen.

Teilfunktionen:
  • Nach Dateinamen sortiert einfügen (beinhaltet Code A)
    • Durch ausprobieren hat sich ergeben, dass Code B nach dem Änderungsdatum sortiert und einfügt
  • Kopfzeilen aller Dateien abgesehen von erster CSV-Datei löschen (beinhaltet Code B)
  • Praktikable Nutzung ohne jeweils vorher anzupassen (beinhaltet Code A)
    • Bei Code B muss die Variable „Ordner“ vor jeder Ausführung mit dem gewünschten Dateipfad initialisiert werden; Zur Not ist dies auch akzeptabel
Code A:
Code:
@echo off &setlocal
>"gesammelt.csv" type nul
for /f "delims=" %%a in ('dir /a-d /b/o:n *.csv^|findstr /vic:"gesammelt.csv"') do (
  set "name=%%~na"
  call :proc
)
goto :eof

:proc
for /f "usebackq delims=" %%a in ("%name%.csv") do (
 REM >>"gesammelt.csv" echo %name% %%a
 >>"gesammelt.csv" echo %%a
)
goto :eof


Code B:
Code:
@echo off & setlocal
set "Ordner=C:\Users\Leon\Documents\"
set "Dateien="%Ordner%"*_data_*.csv"
set "Sammel="%Ordner%"gesammelt.csv"
set /a Skip=10

pushd "%Ordner%"
set "Erste="
for /f "delims=" %%i in ('dir /b /o-d /a-d "%Dateien%" 2^>nul') do set "Erste=%%i"
if not defined Erste (echo Keine passenden Dateien gefunden! & popd & goto :eof)
copy "%Erste%" "%Sammel%">nul
for /f "skip=1 delims=" %%i in ('dir /b /od /a-d "%Dateien%"') do (
    for /f "skip=%Skip% delims=" %%a in ('findstr /n "^" "%%i"') do (
        set "Zeile=%%a"
        setlocal enabledelayedexpansion
        echo(!Zeile:*:=!
        endlocal
    )
)>>"%Sammel%"
popd


Anbei befindet sich noch ein Beispiel, wie eine zusammengefügte CSV-Datei aussehen sollte und die dazugehörigen einzelnen CSV-Dateien.


Ich wäre unglaublich dankbar, wenn mir jemand bei meinem Problem helfen könnte.

Bei Fragen oder Unklarheiten bitte melden.


Mit freundlichen Grüßen

Leon
 

Anhänge

  • 123456789_data_2019_12_01.csv
    242 Bytes · Aufrufe: 375
  • 123456789_data_2019_12_02.csv
    242 Bytes · Aufrufe: 317
  • 123456789_data_2019_12_03.csv
    242 Bytes · Aufrufe: 312
  • 123456789_data_2020_01_01.csv
    242 Bytes · Aufrufe: 308
  • gesammelt.csv
    575 Bytes · Aufrufe: 354
Ich kenne mich mit batch auch nicht aus, aber warum muss es denn überhaupt batch sein? Wenn du doch Python Kenntnisse hast wieso nicht mit pandas?
 
Ausprobiert hab ich das jetzt nicht, aber dieses Thema klingt sehr ähnlich. Auf den ersten Blick sieht das Skript auch gut aus.

Code:
@echo off
del big.one 2> NUL
for %%f in (*.mf) do (
   if not exist big.one (
      copy "%%f" big.one
   ) else (
      for /F  "usebackq skip=1 delims=" %%a in ("%%f") do (
         echo %%a>> big.one
      )
   )
)
set /P fileDate=< big.one
ren big.one filename_%fileDate:~0,-1%.mf


Allerdings möchte ich an dieser Stelle gerne erwähnen: Batch is a bitch!

Wenn du also Kenntnisse in anderen Sprachen hast - wobei sich der Vergleich von Batch mit Programmiersprachen eigentlich verbietet - rate ich dir, das Problem dort zu lösen, selbst wenn obiges Skript funktionieren sollte.
 
horstle schrieb:
Ich kenne mich mit batch auch nicht aus, aber warum muss es denn überhaupt batch sein? Wenn du doch Python Kenntnisse hast wieso nicht mit pandas?

Es muss nicht unbedingt mittels Batch gelöst werden, jedoch hatte ich erste gute Erfahrungen damit gemacht und wollte diesen Weg versuchen weiterzuführen.

Raijin schrieb:
Ausprobiert hab ich das jetzt nicht, aber dieses Thema klingt sehr ähnlich. Auf den ersten Blick sieht das Skript auch gut aus.

Code:
@echo off
del big.one 2> NUL
for %%f in (*.mf) do (
   if not exist big.one (
      copy "%%f" big.one
   ) else (
      for /F  "usebackq skip=1 delims=" %%a in ("%%f") do (
         echo %%a>> big.one
      )
   )
)
set /P fileDate=< big.one
ren big.one filename_%fileDate:~0,-1%.mf


Allerdings möchte ich an dieser Stelle gerne erwähnen: Batch is a bitch!

Wenn du also Kenntnisse in anderen Sprachen hast - wobei sich der Vergleich von Batch mit Programmiersprachen eigentlich verbietet - rate ich dir, das Problem dort zu lösen, selbst wenn obiges Skript funktionieren sollte.

Fast perfekt!

Verwendeter Code:
Code:
@echo off
del big.csv 2> NUL
for %%f in (*.csv) do (
   if not exist big.csv (
      copy "%%f" big.csv
   ) else (
      for /F  "usebackq skip=9 delims=" %%a in ("%%f") do (
         echo %%a>> big.csv
      )
   )
)
set /P fileDate=< big.csv
ren big.csv filename_%fileDate:~0,-1%.csv

funktioniert und erfüllt soweit alle Kriterien, jedoch werden die einzelnen CSV-Dateien doppelt durchlaufen (siehe roter Rahmen im Bild).

Folgender Output entsteht beim Testen mit den Anhängen aus Beitrag #1:
Batch_Test.jpg


Woran könnte das liegen?
 
Ich zitiere mich mal selbst:

Raijin schrieb:
Batch is a bitch!

Während die äußere for-schleife läuft, wird in der Schleife eine big.csv erstellt, die dann wiederum nachträglich in die äußere Schleife aufgenommen und demnach auch bearbeitet wird. Die Quelldateien werden also nicht doppelt ausgelesen, sondern am Ende wird die gerade erstellte big.csv ebenfalls durchlaufen - und da steht ja alles von den Quelldateien drin...................................................

Muss man noch mehr zu Batch sagen?

Wie auch immer, ändere den Namen der big.csv im Skript in big.txt und benennen sie dann NACH der Schleife in big.csv um.
 
  • Gefällt mir
Reaktionen: leonderprofy und PHuV
@Raijin vielen Dank für deine Hilfe!

So funktioniert es:

Code:
@echo off
del gesammelt.txt 2> NUL
for %%f in (*.csv) do (
   if not exist gesammelt.txt (
      copy "%%f" gesammelt.txt
   ) else (
      for /F  "usebackq skip=9 delims=" %%a in ("%%f") do (
         echo %%a>> gesammelt.txt
      )
   )
)
ren gesammelt.txt gesammelt.csv
 
  • Gefällt mir
Reaktionen: Raijin
Zurück
Oben