coldzero89
Goto Top

Zeilensuche in CSV

Moin Moin,

ich habe das Problem das in CSV Dateien Daten stehen die nach "DATUM UHRZEIT" (in einer Spalte) geordnet sind. Diese sind in 15 Minutenwerte gesplittet und für 7 Tage.

Davon habe ich 7 CSV Dateien.
Ich will die 23:45h Werte.

Problem an der ganzen Sache: Datei 1 hat 23:45, Datei 2 hat 23:45, Datei 3 hat 23:46, usw...

Ich habe mir nun gedacht in das ich mit IF Abfragen die Zeit bestimmen kann.

Mein Gedanke verlief folgendermaßen:

Ich habe das eingegebene Datum (Bsp.:18.02.2013, Das Datum in den Dateien ist nach MM.TT.JJJJ geordnert, die drehung der Zahlen ist schon gemacht) und die Festgelegte Zeit 23:45, 23:46, 23:47 usw.... Diesen Wert lass ich mit einer "Zeilen" suche abgleichen mit den einzelnen Zeilen.

Die Einzelnen Spalten sind mit ; getrennt.

Die Abfrage würde nun folgendermaßen - nach meinem Kopf - so aussehen:
IF "%DatumSAA1% 23:45"=="ZEILENVERGLEICH" set "Zeit=23:45"  
IF "%DatumSAA1% 23:46"=="ZEILENVERGLEICH" set "Zeit=23:46"  
IF "%DatumSAA1% 23:47"=="ZEILENVERGLEICH" set "Zeit=23:47"  
IF "%DatumSAA1% 23:48"=="ZEILENVERGLEICH" set "Zeit=23:48"  
IF "%DatumSAA1% 23:49"=="ZEILENVERGLEICH" set "Zeit=23:49"  

das problem was ich nun habe: Wie bau ich den Zeilenvergleich? Da scheiter ich gedanklich total dran und komm nicht im ansatz an eine Lösung.

Falls ich das Script posten soll, sagt es, ist für den Teil an sich aber unwichtig.

Danke für eure Ansätze und Hilfe.

Gruß ColdZero

Content-ID: 202565

Url: https://administrator.de/forum/zeilensuche-in-csv-202565.html

Ausgedruckt am: 22.12.2024 um 15:12 Uhr

64748
64748 28.02.2013 aktualisiert um 16:32:33 Uhr
Goto Top
Hallo,

mach es statt als Batch-Datei mit einer Programmiersprache die Reguläre Ausdrücke kennt. Z.B: Suche nach
if ( $line =~ m/23:4\d/ ) 
, so geht es mit Perl, sollte mit VB ähnlich sein. Der Ausdruck bedeutet, dass nach "23:4x" gesucht wird, wobei x eine Ziffer von 0 bis 9 ist.

Wenn Du nun eine Variable brauchst, die nur die Zeit enthält, dann wäre das so
if ( $line =~ m/(23:4\d)/ ) {
    $zeit = $1 ;
}
weil $1 den Ausdruck innerhalb der Klammern enthält.

Markus
ColdZero89
ColdZero89 28.02.2013 aktualisiert um 16:53:13 Uhr
Goto Top
Moin,

das ganze Script besteht nun schon aus Batch und ich arbeite schon relativ lang da dran.
Bis auf Batch verstehe ich grundlagen von VBS/VBA aber nicht sowas komplexes wie ich vor habe.
Das Problem ist halt es steht nicht immer eine 5 dahinter und ich brauch die Zeit von 23h weil dann die Energiewerte für den Tag stehen und die Werte nicht mehr steigern.

Es ist halt in der ersten Datei: 23:45 in der zweiten 23:45 in der dritten 23:46, in der vierten 23:47 usw. Mal ist es aber auch so das in der ersten 23:45 ist und in der zweiten schon die 23:46. Es ist halt unregelmäßig deswegen muss das flexibel sein.

Aber danke für deinen vorschlag.

EDIT: nu hast du deinen beitrag bearbeitet xD
Ja nur an sich ok, nur wie vergleiche ich immer die erste Zeile? bzw such den wert direkt? Ne VB aufrufen die vorher geschrieben wurde an sich keine schlechte idee...

Gruß Zero
64748
64748 28.02.2013 um 16:36:45 Uhr
Goto Top
Sorry, ich hatte gerade meine Antwort von oben nochmal angepasst weil ich Dich falsch verstanden hatte.

Frage: welche Daten brauchst Du denn? also wie sieht die Datenstruktur aus, die am Ende rauskommen soll? Vielleicht postest Du mal eine Beispielzeile aus der csv-Datei und dazu die Daten wie sie vorliegen sollen, wenn alles fertig ist.

Aber im Ernst, komplexe Dinge in Batch, das geht zwar, ist aber sehr unkomfortabel und fehleranfällig.

Markus
ColdZero89
ColdZero89 28.02.2013 um 17:05:39 Uhr
Goto Top
Moin,

ok zwischen meinem Edit und dem schreiben deines Posts lag nun grad ein Meeting.

Welche Daten ich brauche ist alles schon funktional. Das betrifft 7 von 9 Dateien die diese Zeitprobleme haben. Das mit den Werten die aus der CSV rausgeschrieben werden sollen funktioniert halt schon, das was fehlt ist nun das Flexible abgleichen der Zeit, bzw. der Flexible aufruf der Zeit.

Datum und Uhrzeit sind in einer Spalte wenn ich die CSV im Excel öffne.

Das Datum wird vom User eingegeben und die Zeit dann variabel rausgesucht bzw abgeglichen in der Datei.

Is halt irgendwie pieeeep zu erklären face-big-smile

Sollte irgendwie noch unklarheit sein, frag bitte ich probiere es dann so genau wie möglich zu erklären.#

Mir kam nun gerade der Gedanke das ganze nicht mit 10 If abfragen zu machen sondern einmal eine For schleife und die Minute hochzählen lassen und in der for ne IF abfrage rein und an die Zeit dann die einzelne Minute einfach dranhängen.

Zeile aus so einer CSV:

Datum Uhrzeit;Modulstrahlung_M1;Modulstrahlung_M2;Modulstrahlung_M3;Modultemperatur_M1;Modultemperatur_M2;Modultemperatur_M3;Raum_Zuluft_Drossel_Temperatur;Umgebungstemperatur;WR1_Ableitstrom;WR1_GESAMTENERGIE;WR1_I_AC_L1;WR1_I_AC_L2;WR1_I_AC_L3;WR1_I_DC_IST;WR1_JAHRESENERGIE;WR1_KUEHLKOERPERTEMP;WR1_MONATSENERGIE;WR1_P_AC_IST;WR1_P_DC_IST;WR1_Q_AC_IST;WR1_TAGESENERGIE;WR1_Teilspannung_M;WR1_Teilspannung_P;WR1_U_AC_L1;WR1_U_AC_L2;WR1_U_AC_L3;WR1_U_DC_IST;WR2_Ableitstrom;WR2_GESAMTENERGIE;WR2_I_AC_L1;WR2_I_AC_L2;WR2_I_AC_L3;WR2_I_DC_IST;WR2_JAHRESENERGIE;WR2_KUEHLKOERPERTEMP;WR2_MONATSENERGIE;WR2_P_AC_IST;WR2_P_DC_IST;WR2_Q_AC_IST;WR2_TAGESENERGIE;WR2_Teilspannung_M;WR2_Teilspannung_P;WR2_U_AC_L1;WR2_U_AC_L2;WR2_U_AC_L3;WR2_U_DC_IST
10.30.2006 23:46:00;1,00;0,00;0,00;4,35;0,00;0,00;9,00;5,92;0,28;303991,00;0,00;0,00;0,00;0,00;99443,00;17,00;6756,00;0,00;0,00;0,00;0,90;200,00;200,00;233,00;232,00;232,00;0,00;0,00;310976,00;0,00;0,00;0,00;0,00;106428,00;16,00;7728,00;0,00;0,00;0,00;0,00;200,00;200,00;235,00;232,00;232,00;0,00


Noch fragen? face-big-smile

Gruß Zero
64748
64748 28.02.2013 um 17:20:54 Uhr
Goto Top
Zitat von @ColdZero89:
Noch fragen? face-big-smile
Jetzt sind alle Klarheiten beseitigt face-wink

Also Tipp, wenn Du die Datei mit Excel öffnest, dann mach alles in Excel. Das kann ja kein großes Problem sein, die benötigten Daten in Excel herauszusuchen.

Ansonsten, wenn es mit einem Skript gehen soll, dann wird man normalerweise die Datei zeilenweise mit ';' als Trenner splitten und in ein Array schreiben. Dann musst Du nur noch die passenden Einträge des Arrays (entsprechend den Spalten in der CSV-Datei bzw. Excel) bearbeiten. Es wäre dann z.B.
Array = Datum
Array[1] = Zeit
usw.
Du musst Dir klar werden, welches Werkzeug Du benutzen möchtest, mit Batch kann ich nicht helfen.

Markus
ColdZero89
ColdZero89 28.02.2013 um 17:30:06 Uhr
Goto Top
Moin,

ich kann Datum und Zeit nicht trennen da Datum und Zeit in EINER Spalte stehen, diese sind durch kein ";" getrennt.

Ich will halt das eingegebene Datum durch eine Uhrzeit ergänzen die ich vorgebe und dieses wird dann in in ne Variable geschrieben das Zeit = XX:YY ist und dann geht es zur verarbeitung.

Raubt mir den letzten Nerv ^^

SO wie ich das nun haben möchte und auch denke das es funktionieren tut - ich nur nicht wirklich weiß wie:

(Nur Skizze)
For i=40 i+1 und rausspringen wenn i=51 (
if "%Datum% 23:%%i"=="ZEILENVERGLEICH" set Zeit=23:%%i
)

Und im Prozess wird die Zeit dann so verwendet... Problem was mri nun graf auffällt irgendwo muss ich die Datei noch angeben die er verwenden soll. Grml.
Dies ist wiederrum vielleicht mti findstr zu lösen anstatt einem if. Check ich morgen mal - muss nu los.

Ich hoffe jemand kann mir weiterhelfen.

Gruß Zero

Gruß Zero
Friemler
Friemler 28.02.2013 aktualisiert um 22:32:38 Uhr
Goto Top
Hallo Zero,

teste mal folgendes:
@echo off & setlocal

set "BaseFolder=."  
set "Files="file1.csv" "file2.csv" "file3.csv" "file4.csv" "file5.csv" "file6.csv" "file7.csv""  

set "TheDate=10.30.2006"  
set "Hour=23"  
set "Minute=45"  

for %%f in (%Files%) do (
  for /f eol^=^ delims^= %%l in ('findstr /b /r /c:"%TheDate% %Hour%:" "%BaseFolder%\%%~f"') do (  
    for /f eol^=^ tokens^=^3^ delims^=^:^  %%m in ("%%l") do (  
      if %%m geq %Minute% echo %%~f: %%l
    )
  )
)

Erläuterung:

Variable BaseFolder (Zeile 3) Das Verzeichnis, in dem die CSV-Dateien abgelegt sind.
Variable Files (Zeile 4) Die Liste der Dateinamen der zu untersuchenden CSV-Dateien, jeweils in Anführungszeichen eingeschlossen
und durch Freizeichen voneinander getrennt.
Variable TheDate (Zeile 6) Das Datum in dem Format, wie es in den CSV-Dateien notiert ist. Die Variable darf nicht Date heißen,
da es schon eine Systemvariable mit diesem Namen gibt.
Variable Hour (Zeile 7) Der Stundenanteil der gewünschten Uhrzeit.
Variable Minute (Zeile 8) Der Minutenanteil der gewünschten Uhrzeit.

Die For-Schleife in Zeile 10 iteriert durch die Liste der Namen der CSV-Dateien.

Die FOR-Schleife in Zeile 11 extrahiert aus der aktuellen CSV-Datei die Zeilen, die mit dem gewünschten Datum und einer Zeitangabe mit der gewünschten Stunde beginnen.

Die FOR-Schleife in Zeile 12 extrahiert aus den gefundenen Zeilen die Minutenangabe.

Ist die gefundene Minutenangabe größer oder gleich der gewünschten Minutenangabe, wird in Zeile 13 der Name der aktuellen CSV-Datei sowie die komplette Zeile ausgegeben.

Die ^-Zeichen in den Köpfen der FOR-Schleifen in Zeile 11 und 12 sind Escape-Zeichen, die in den Optionen-String (EOL= DELIMS= usw.) der FOR-Schleife eingefügt werden müssen, da die Optionen nicht in Anführungszeichen eingeschlossen sind. Das ist notwendig, um als EOL (End Of Line) KEIN Zeichen festzulegen. Per Default ist das Semikolon als EOL definiert, was bei einer CSV-Datei aber zu den Daten gehört und nicht interpretiert werden darf. Wir wollen auch kein anderes Zeichen als EOL zulassen, das ist nur mit obiger Methode machbar. Siehe hier.

Datum und Uhrzeit müssen in der gleichen Zeile stehen.

Gruß
Friemler
ColdZero89
ColdZero89 01.03.2013 um 11:16:19 Uhr
Goto Top
Moin,

ähm ja.... das muss ich grad erstmal futtern und verarbeiten.

Die Files kann ich sicherlich durch eine Variable ersetzen die den Pfad vorgibt und dann *.csv angeben oder?

Herrjeh das sieht echt übelst verworren aus. Führt sicherlich zu dem was ich will.
Ich muss es nur erweitern durch eine Variable abfrage der Minuten. Somit würde dein Script funktionieren da die Stunde FIX ist.
Ich habe mein Batch nun mal anegfügt, damit eventuell gesehen wird wo ich stehe. Es ist bestimmt nicht das schönste und kann sicherlich vereinfacht werden, ich komm so aber sehr gut klar und hab den überblick.

Ich musste SAA 1 und SAA 2 + 3 unterscheiden da bei SAA 1 das Datum anders ist und die Spalte in der die Daten stehen eine andere ist.

Ich hoffe das Hilft beim verstehen ^^

@echo off & setlocal enabledelayedexpansion

rem Script zur Verarbeitung der Wochendatein von Saarbrücken/Ensheim 1+2+3 zur extrahierung der Monatswerte.
rem 1.0 Verarbeitung der Datei für Saarbrücken 2 und 3
rem 2.0 Erweiterung des Scriptes durch ein Menü
rem 3.0 Erweiterung des Scriptes mit Saarbrücken 1 mit eigener ProcessLine
rem V2.5 Kevin Lange, 26.02.2013


rem Deklaration von Variablen
set "AW=0"  

rem Programmbegrüßung
echo Programm zum Verarbeiten der Wochendatein von Saarbruecken 1+2+3
echo =======================================================

rem Datum wird per Hand eingegeben
:datum
set /p "Datum=Bitte Datum im Format TT.MM.JJJJ eingeben: "  
for /f "tokens=1-3 delims=." %%G IN ('echo %Datum%') DO set DatumSAA1=%%H.%%G.%%I  

rem Datum wird auf Format geprüft	
echo %Datum%|findstr /X "[0-3][0-9]\.[0-1][0-9]\.2[0-9][0-9][0-9]">nul && goto :menu	  
echo =======================================================
echo Fehler! Datum muss im Format TT.MM.JJJJ eingegeben werden.
echo =======================================================
GOTO :datum	
	
rem Auswahlmenü welche Datein behandelt werden sollen	
:menu
echo Bitte Auswahl der Anlage treffen
echo [1] Saarbruecken 1 PVU1
echo [2] Saarbruecken 1 PVU2
echo [3] Saarbruecken 1 PVU3
echo [4] Saarbruecken 1 PVU4
echo [5] Saarbruecken 1 PVU5
echo [6] Saarbruecken 1 PVU6
echo [7] Saarbruecken 1 PVU7
echo [8] Saarbruecken 2
echo [9] Saarbruecken 3
echo [10] Datum aendern
echo [11] Programmende
set /p "AW=Bitte Auswahlnummer eingeben: "  

rem Auswahl wird geprüft, ob Zahl zwischen 1 und 11 liegt
echo "#1#2#3#4#5#6#7#8#9#10#11#"|findstr /c:"#%AW%#">nul && goto :wahl  
echo =======================================================
echo Fehler! Auswahl darf nur zwischen 1 und 11 liegen
echo =======================================================
GOTO :menu

rem Springt in den ausgewählten Case und danach in den Programmabschnitt
:wahl
GOTO CASE_%AW%
	:CASE_1
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU1 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU1
	:CASE_2
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU2 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU2
	:CASE_3
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU3 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU3
	:CASE_4
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU4 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU4
	:CASE_5
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU5 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU5
	:CASE_6
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU6 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU6
	:CASE_7
		echo =======================================================
		echo Programm fuer Saarbruecken 1 PVU7 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA1PVU7
	:CASE_8
		echo =======================================================
		echo Programm fuer Saarbruecken 2 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA2
	:CASE_9
		echo =======================================================
		echo Programm fuer Saarbruecken 3 wird ausgefuehrt
		echo =======================================================
	GOTO :SAA3
	:CASE_10
	GOTO :datum
	:CASE_11
	GOTO :ende

rem Setzen der Variablen für die Verarbeitung der Daten von SAA1
:SAA1PVU1
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU1"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU1.csv"  
GOTO umwandelnSAA1
:SAA1PVU2
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU2"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU2.csv"  
GOTO umwandelnSAA1
:SAA1PVU3
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU3"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU3.csv"  
GOTO umwandelnSAA1
:SAA1PVU4
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU4"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU4.csv"  
GOTO umwandelnSAA1
:SAA1PVU5
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU5"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU5.csv"  
GOTO umwandelnSAA1
:SAA1PVU6
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU6"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU6.csv"  
GOTO umwandelnSAA1
:SAA1PVU7
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA1PVU7"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA1PVU7.csv"  
GOTO umwandelnSAA1
	
rem Setzen der Variablen für die Verarbeitung der Daten von SAA2
:SAA2
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA2"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA2.csv"  
set "Zeit=23:50"  
GOTO umwandelnSAA23

rem Setzen der Variablen für die Verarbeitung der Daten von SAA3
:SAA3
set "Ein=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\SAA3"  
set "Aus=D:\Users\kela\Documents\Scripte\SAARBRUECKEN_TEST\Monat_SAA3.csv"  
set "Zeit=23:50"  
GOTO umwandelnSAA23

rem Ersetzen von Zeichen mit anschließendem Prozessaufruf für Saarbrücken 1
:umwandelnSAA1
for /f "delims=" %%i in ('findstr "%Zeit%" "%Ein%\*.csv"^|findstr "%DatumSAA1%"') do (  
    set "ZeileEin=%%i"  
    set "ZeileEin=!ZeileEin:,=@!"  
    call :ProcessLineSAA1 !ZeileEin:;= !
)
set AW=0
GOTO :menu

rem Ersetzen von Zeichen mit anschließendem Prozessaufruf für Saarbrücken 2 und 3
:umwandelnSAA23
for /f "delims=" %%i in ('findstr "%Zeit%" "%Ein%\*.csv"^|findstr "%Datum%"') do (  
    set "ZeileEin=%%i"  
    set "ZeileEin=!ZeileEin:,=@!"  
    call :ProcessLineSAA23 !ZeileEin:;= !
)
set AW=0
GOTO :menu

rem Ausführendes Programm für Saarbrücken 1
:ProcessLineSAA1
set "ZeileAus=%Datum% %Zeit%"  
for /l %%a in (1,1,18) do shift
set "ZeileAus=%ZeileAus%;%1"  
for /l %%a in (1,1,19) do shift
set "ZeileAus=%ZeileAus%;%1"  
>>"%Aus%" echo %ZeileAus:@=,%  
GOTO :eof

rem Ausführendes Programm für Saarbrücken 2 und 3
:ProcessLineSAA23
set "ZeileAus=%Datum% %Zeit%"  
for /l %%a in (1,1,20) do shift
set "ZeileAus=%ZeileAus%;%1"  
for /l %%a in (1,1,21) do shift
set "ZeileAus=%ZeileAus%;%1"  
for /l %%a in (1,1,21) do shift
set "ZeileAus=%ZeileAus%;%1"  
for /l %%a in (1,1,21) do shift
set "ZeileAus=%ZeileAus%;%1"  
>>"%Aus%" echo %ZeileAus:@=,%  
GOTO :eof

rem Programmende
:ende
exit