chrislm
Goto Top

Eine Tabelle aus einer großen CSV exportieren

Ich habe gesehen das du ein Meister der batchdateien bist. Ich habe dort ein kleines Problem mit einer, ich möchte gerne aus einer CSV eine bestimmte Tabelle seperat in eine Datei schreiben. In dieser Tabelle befinden sich bildnahmen welche ich später durch eine schleife automatisch kopieren will. Leider hat die CSV recht viele Spalten sodass ich es nicht geschaft bekomme saubere daten zu bekommen. Das problem schein darin zu liegen das verschiedene Felder nicht ausgefüllt sind und so teilweise ignoriert werden, meien Spalte ist die 60ste in der Tabelle... Setze ich die Tabelle auf spalte 1 oder 7 z. b. habe ich auch die Daten drin. Aber je weiter hinter das geht umso schlimmer wird es. in meinem Falle nun wird keine Datei mehr angezeigt.
Was kann ich denn nun tun?

for /f "tokens=60,61,61 delims=;" %%a in (muster.csv) do echo %%a>>test.csv

Oder kann ich auch nach Feldnamen gehen....?

vielen dank

Content-ID: 181219

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

Ausgedruckt am: 22.11.2024 um 16:11 Uhr

bastla
bastla 29.02.2012 um 11:55:14 Uhr
Goto Top
Hallo chrislm und willkommen im Forum (ja, wir mögen hier eine - zumindest kurze - Begrüßung)!

Abgesehen von der Tatsache, dass "for /f" keine 60 Tokens verwenden kann, wäre es sinnvoll, zumindest eine Beispielzeile (in "Code"face-wink zu posten, damit ersichtlich wird, welche Daten (insbes auch hinsichtlich Sonderzeichen) enthalten sind ...

Und nur zur Sicherheit: Es geht ausschließlich um die Spalte 60?

Ansonsten: Gibt es irgend einen Einwand Deinerseits gegen die Verwendung von VBS (zur Not auch innerhalb eines Batches)?

Grüße
bastla
chrislm
chrislm 29.02.2012 um 13:10:29 Uhr
Goto Top
Es geht mit um die Fremdkunden ID2:
ID;ORDER_ID;Abotyp;Abocode;Objekt;Version;RE_ANREDE;RE_VORNAME;RE_NACHNAME;RE_ZUSATZ;RE_STRASSE;RE_PLZ;RE_STADT;RE_LAND;RE_TEL;RE_FAX;RE_MAIL;Zahlungsart;BLZ;Kontonummer;Bank;WE_ANREDE;WE_VORNAME;WE_NACHNAME;WE_ZUSATZ;WE_STRASSE;WE_PLZ;WE_STADT;WE_LAND;WE_TEL;WE_FAX;WE_MAIL;Praemienartikel;Artikel_Nr;LA_ANREDE;LA_VORNAME;LA_NACHNAME;LA_ZUSATZ;LA_STRASSE;LA_PLZ;LA_STADT;LA_LAND;LA_TEL;LA_FAX;LA_MAIL;Zahlungsrhythmus;VKZ;Vertreter_NR;Lieferbeginn;Fremdkunden ID;Freiheftlieferung;Gutschr_ für Bankeinzüge €;Orga_Nummer;GEB_Datum;ZahlWahlDatum;Praemienartikel2;Praemienartikel3;Werbeverbot;Vertragsdatum;Fremdkunden ID2;Rabatt;Fremdkunden ID_lang;JJMMHH;konstante_Hefte;Wiederholung;Hefte_bis_LE

Leider kann ich kein visual basic.... wenn man es als Befehl in eine Batch stecken kann, währe das auch OK. In der FremdkundenID 2 stehen die Bilder welche ich dann aus einem Ordner kopieren muss.
Skyemugen
Skyemugen 29.02.2012 um 14:47:23 Uhr
Goto Top
Aloha,

hm, tut es diese Lösung?

@echo off & setlocal

for /f "usebackq tokens=31,* delims=;" %%s in ("datei.csv") do call :Ablauf "%%t"  
pause

:Ablauf
for /f "tokens=29-31,* delims=;" %%m in (%1) do (  
	echo %%m;%%n;%%o>>"neu.csv"  
)
goto :eof

müsste doch genau 60, 61, 62 sein

greetz André
chrislm
chrislm 29.02.2012 um 14:58:44 Uhr
Goto Top
Vielen dank erstmal für die Antworten.

Es klappt leider nur soweit das ich dir Kopfzeile exportiert habe aber keine Daten..
Skyemugen
Skyemugen 29.02.2012 um 15:01:18 Uhr
Goto Top
Aloha,

achja in deinem Bandwurm eines Satzes stand ja noch etwas von nicht ausgefüllte Spalte, und wenn die Laufvariable nicht definiert wird, passiert natürlich auch nichts *pfeif*

Genau deswegen mag ich ja so den Batch-Bereich, die EPs sind immer so ... nichtssagend.

greetz André
it-frosch
it-frosch 29.02.2012 um 15:11:26 Uhr
Goto Top
Hallo chrislm,

wenn in einem Datensatz nicht alle Felder befüllt sind sieht er dann so:

ID;;Abotyp ....... ->ORDER_ID ist nicht befüllt

oder so:

ID;Abotyp ....... ->ORDER_ID ist nicht befüllt

aus?

grüße vom it-frosch
chrislm
chrislm 29.02.2012 um 15:12:30 Uhr
Goto Top
Ich würde es ja uach mit vbs lösen nur leider habe ich bisher keinerlei funktionierende Codeschnipsel gefunden die ich für meine Bedürfnisse ändern kann...
chrislm
chrislm 29.02.2012 um 15:31:49 Uhr
Goto Top
Zitat von @it-frosch:
Hallo chrislm,

wenn in einem Datensatz nicht alle Felder befüllt sind sieht er dann so:

ID;;Abotyp ....... ->ORDER_ID ist nicht befüllt

oder so:

ID;Abotyp ....... ->ORDER_ID ist nicht befüllt

aus?

grüße vom it-frosch
Die spalter seind einfach leer, in der CSV stehen nur zu hauf ;
bastla
bastla 29.02.2012 um 15:48:51 Uhr
Goto Top
Hallo chrislm!

Na dann:
Ein = "muster.csv"  
Aus = "test.csv"  
Delim = ";"  
FeldNr = 60
Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)
For Each Zeile In Zeilen
    T = T & vbCrLf & Split(Zeile, Delim)(FeldNr - 1)
Next
fso.CreateTextFile(Aus).Write Mid(T, 3)
Grüße
bastla
chrislm
chrislm 29.02.2012 um 15:59:00 Uhr
Goto Top
Sorry, war ein Tipfehler von mir, es geht. Aber die Einträge sind in " ", das müsste noch weg, dann ist es perfekt
bastla
bastla 29.02.2012 um 16:06:36 Uhr
Goto Top
@skye
Zum Thema nicht ausgefüllte Spalte könntest Du ja in ähnlichen Fällen etwa so vorgehen:
... set "Zeile=%%i" & call :ProcessLine  
...

:ProcessLine
set "Zeile=%Zeile:;;=; ;%"  
set "Zeile=%Zeile:;;=; ;%"  
for /f "tokens=15 delims=;" %%i in ("%Zeile%") do echo %%i  
Grüße
bastla
bastla
bastla 29.02.2012 um 16:08:32 Uhr
Goto Top
Hallo chrislm!

Das dürfte daran liegen, dass sich am Ende der letzten Zeile noch ein Zeilenumbruch befindet (eine Zeile, deren Feldanzahl nicht stimmt, sollte es ja wohl nicht geben) - sollte dann aber so gehen:
Ein = "muster.csv"  
Aus = "test.csv"  
Delim = ";"  
FeldNr = 60
Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)
For Each Zeile In Zeilen
    If Trim(Zeile) <> "" Then T = T & vbCrLf & Split(Zeile, Delim)(FeldNr - 1)  
Next
fso.CreateTextFile(Aus).Write Mid(T, 3)
Grüße
bastla
chrislm
chrislm 29.02.2012 um 16:26:01 Uhr
Goto Top
Ja, es geht, habs mittlerweile, aber die Zeilen stehen in " ", bekommt man die noch weg...?
bastla
bastla 29.02.2012 um 16:31:57 Uhr
Goto Top
Hallo chrislm!
Wenn es sich um Dateinamen handelt, sind die Anführungszeichen doch eher nützlich ...

... anyhow:
    If Trim(Zeile) <> "" Then T = T & vbCrLf & Replace(Split(Zeile, Delim)(FeldNr - 1), """", "")
Grüße
bastla
chrislm
chrislm 29.02.2012 um 16:47:47 Uhr
Goto Top
Ich wollte danach die Dateien die dort in der Datei stehen als quelle nutzen um genau diese aufgeführten Dateien in einen beliebigen Ordnuer zu kopieren. Ich denke theoretisch kann man das auch direkt über vba machen... wie würde das denn dann aussehen? Wenn ich nun hin gehe und führe copy von P:\bilderarchiv auf c:\bilder z.b...?
Skyemugen
Skyemugen 29.02.2012 um 17:50:28 Uhr
Goto Top
Aloha bastla,

ja, kam mir auch der Gedanke ABER wenn die Zeile jetzt mit ";" anfängt, dann tut sich mit der Schleife so oder so nichts, da kann ich drehen wie ich will, Zeilen, die mit Semikolon beginnen, ignoriert er, selbst wenn ich kackedreist mit 'findstr /B ";" "datei.csv"' arbeite, ohne Schleife gibt er mir die Zeile aus, mit Schleife wird "Zeile=" und das war's.

Da ich darauf keine Lösung bisher fand, ließ ich es ganz, theoretisch sollte aber Spalte eins ja gefüllt sein, also könnte man schon

siehe unten
durcharbeiten lassen

greetz André
it-frosch
it-frosch 29.02.2012 um 18:05:52 Uhr
Goto Top
Hallo Chrislm,

dann importiere die CSV mal so.

1. Dateiendung von CSV nach AAA umbenennen.
2. Import als Textdatei mit ; als Trennzeichen.

Jetzt sollten alle Daten des Feldes 60 in einer Spalte untereinander stehen.

Das Auslesen der Daten haben die Anderen bestimmt schon beschrieben.

grüße vom it-frosch
bastla
bastla 29.02.2012 um 18:31:54 Uhr
Goto Top
@skye
Zeilen, die mit Semikolon beginnen, ignoriert er
... es sei denn, Du legst mit
for /f "eol=§ tokens=31,* delims=;" %%m ...
ein anderes EOL-Zeichen fest ...

Grüße
bastla
bastla
bastla 29.02.2012 um 18:39:58 Uhr
Goto Top
Hallo chrislm!

Dann etwa so (wobei es den Zielordner schon geben muss und keine gleichnamigen Dateien im Zielordner existieren dürfen):
Ein = "muster.csv"  
Quelle = "P:\bilderarchiv\" '\ am Ende beachten  
Ziel = "c:\bilder\" '\ am Ende beachten  
Delim = ";"  
FeldNr = 60
Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)
For Each Zeile In Zeilen
   If Trim(Zeile) <> "" Then fso.CopyFile Quelle & Replace(Split(Zeile, Delim)(FeldNr - 1), """", ""), Ziel  
Next
Grüße
bastla
pieh-ejdsch
pieh-ejdsch 29.02.2012 um 19:06:39 Uhr
Goto Top
moin bastla &andré,

also ich habe das Jetzt mal so zusammengefasst
@echo off &setlocal disabledelayedexpansion
:: echo on
set  "InFile=D:\Testordner\Datei.csv"  
set "OutFile="  
set   "Cells=20 45 50 60 61 62 63 64 65 70 80 90"  


if defined Outfile (set "Um=>") else set "Um="  
%Um% %OUTFILE% (
for /f usebackqDelims^=^ eol^= %%i in ("%Infile%") do (  
	set Line="%%i"  
	set "cell=0"  
	set "incell=0"  
	set "check=1"  
	call :ReadCell %cells%
	echo(
)
)
if not defined OutFile >&3 pause
goto :eof

:ReadCell
if %incell% neq 0 if %incell% equ %1 (
	<nul set /p ="  
	if "%2" equ "" goto :eof  
	<nul set /p =";"  
	set /a "cell =%2-%1"  
	shift
) 
if %cell% equ 0 set /a cell =%1
2>nul set /a x=1/((cell-1)/30) && set /a Cell -=30 , Token=30 || set /a Token=Cell
set /a incell +=Token
setlocal enabledelayedexpansion
if defined check set "Line=!Line:;=";"!"  
for /f "Tokens=%Token%* delims=;" %%a in ("!Line!") do endlocal&(set "Line=%%b"  
	if %incell% equ %1 <nul set /p ="%%~a"  
	set "ChecK="  
	goto :ReadCell
)

PS.
for /f "delims=" %%i in ('findstr /n "^" "datei.csv"') do (set Line=%%i  
  set "Line=!Line:*:=!"  
 call untenrum
)
... solte immer in der Schleife funktionieren

Gruß Phil
bastla
bastla 29.02.2012 um 19:15:22 Uhr
Goto Top
Hallo PH!

Hattest Du eigentlich mit %Um% auch noch etwas vor?

Grüße
bastla
pieh-ejdsch
pieh-ejdsch 29.02.2012 um 19:21:19 Uhr
Goto Top
Oh vergessen.
Ähhm - ja die Umleitung.

Mach ich gleich mal rein

Gruß Phil
Skyemugen
Skyemugen 29.02.2012 um 19:22:55 Uhr
Goto Top
Aloha bastla,

ach dammit, stimmt ja, dieses gottverdammte Semikolon ist ja der default bei eol, meine Fresse, was die Redmonder Praktikanten sich dabei gedacht haben, ist mir schleierhaft.

Ich dreh voll am Rad, mich macht die cmd heute so gaga und fertig, den Passierschein A-38 bitte *wuaaaaaaaargh*

@echo off & setlocal
for /f usebackqDelims^=^ eol^= %%s in ("datei.csv") do (  
	set "Zeile=%%s"  
	echo %%s^|findstr /B ";">nul && set "Zeile= %%s"  
	call :Ablauf
)
pause
goto :eof

:Ablauf
set "Zeile=%Zeile:;;=; ;%"  
set "Zeile=%Zeile:;;=; ;%"  
for /f "tokens=31,* delims=;" %%m in ("%Zeile%") do call :Bereich "%%n"  
goto :eof

:Bereich
for /f "tokens=29,* delims=;" %%i in (%1) do echo %%i>>"neu.csv"  
goto :eof

ich verstehe es nicht,. die Zeile wird immer "%%s", ich habe erst versucht im Ablauf set "Zeile= %Zeile%", ja hat er wunderbar im set übernommen, war ihm in der Schleife dann aber wieder ###egal, sodass die Tokens nicht stimmten, also ewig rumgebastelt, momentan passen die Tokens aber eigentlich ist es nicht korrekt und wenn ich
echo %1|findstr /B ";">nul && set "Zeile= %1" in den Ablauf reinnehme (mit der Anpassung beim call), ist es ihm auch wieder ###egal ... ich blick's nicht, ehrlich


edit: *brabbel*
edit: siehe bastlas Kommentar
edit: siehe Phils Kommentar
bastla
bastla 29.02.2012 um 19:24:54 Uhr
Goto Top
... und was mir noch aufgefallen ist: In Zeile 8 hätte ich eher "Outfile" erwartet ... hat sich/hast Du inzwischen erledigt ...

Grüße
bastla
bastla
bastla 29.02.2012 um 19:28:40 Uhr
Goto Top
Hallo Skye!
echo %1|findstr /B ";">nul && set "Zeile= %1"
Woher hast Du %1, und steht das ggf unter Anführungszeichen?

Übrigens: Wenn nicht gerade Feld 1 gesucht ist, macht's ja eigentlich nix, wenn in allen Zeilen ein Leer- oder anderes Zeichen an den Anfang montiert wird ...

Grüße
bastla
Skyemugen
Skyemugen 29.02.2012 um 19:40:30 Uhr
Goto Top
Aloha bastla,

FUUUUUUUUUUUUUU (kennst du das passende Bild dazu?) der cmd

das ist so hirnverbrannt, dass es wirklich nur in der folgenden Konstellation funktioniert:

*brabbel* was ich alles an Möglichkeiten mit %1 und %~1 hatte aber neee, alles auf %~1 bis dato natürlich noch nicht, heißt also, oben müsste es dann einfach nur echo %%s sein, leck mich doch fett, ich geh Abend essen. Es macht für mich keinen Sinn.

Danke & greetz

André
pieh-ejdsch
pieh-ejdsch 29.02.2012 um 19:54:05 Uhr
Goto Top
Hi,

also
for /f usebackqDelims^=^ eol^= %%s in ("datei.csv") do ( ....  
Tut es mit jedem Zeichen am Anfang

Gruß Phil
Skyemugen
Skyemugen 29.02.2012 um 19:59:44 Uhr
Goto Top
Aloha Phil,

jepp kam mir in den Sinn, war aber nicht mehr ganz sicher, wo überall maskiert werden musste und verwarf es wieder ;D

Muss ich mir wirklich mal einprägen, ist ja doch häufiger nützlich in letzter Zeit.

greetz André
bastla
bastla 29.02.2012 um 20:17:23 Uhr
Goto Top
Hallo PH!

Zur Not sollte es auch mit
for /f "usebackq tokens=* eol=" %%s in ("datei.csv") do ( ....
gehen ...

Grüße
bastla
Skyemugen
Skyemugen 29.02.2012, aktualisiert am 18.10.2012 um 18:50:11 Uhr
Goto Top
Aloha bastla,

theoretisch ...

Tutorial zur FOR-Schleife

greetz André
pieh-ejdsch
pieh-ejdsch 29.02.2012 um 20:27:48 Uhr
Goto Top
Hi bastla,
ja da ist dann das Anführungszeichen das EndOfLine Zeichen.

Gruß Phil
Skyemugen
Skyemugen 29.02.2012 um 20:30:31 Uhr
Goto Top
Aloha Phil,


.. wobei, wenn " als erstes Zeichen vorkommt, klappt es mit deiner Variante hier auch nicht ... also in der Endausgabe ;D

... aber das liegt wohl an der gesamten Verarbeitung, da kann ich eol auch auf ¬ setzen

Hmm, warum eigentlich, ist ja somit noch nicht fehlerfrei *grummel*

greetz André
bastla
bastla 29.02.2012 um 20:36:31 Uhr
Goto Top
Hallo Skye und PH!
da kann ich eol auch auf ¬ setzen
Amen. face-wink

Grüße
bastla

P.S.: ... oder VBS verwenden ... face-wink
pieh-ejdsch
pieh-ejdsch 29.02.2012 um 20:39:45 Uhr
Goto Top
das habe ich oben schon eingebaut.

man - Was für ein Rattens-chwanz (<--oh Gott die Zensur schlägt wider zu - so ein Unfug das sind doch deutsche Wörter) wieder geworden ist.

Immer diese Tabellen- und Textbearbeitung.

Gruß Phil
chrislm
chrislm 01.03.2012 um 08:21:54 Uhr
Goto Top
Dort bekomme ich einen Fehler, denn er versucht auch die Fremdkunden ID2 zu kopieren die es natürlich nciht gibt. Ich habs getestet, wenn ich die Spalte umbenenne zu Bild1.jpg dann legt er los. Kann man ihn dazu bringen erst ab zeile 2 zu beginnen..?
bastla
bastla 01.03.2012 um 10:38:21 Uhr
Goto Top
Hallo chrislm!
Kann man ihn dazu bringen erst ab zeile 2 zu beginnen..?
Kann "man" - soll man auch? face-wink

Ein = "muster.csv"  
Quelle = "P:\bilderarchiv\" '\ am Ende beachten  
Ziel = "c:\bilder\" '\ am Ende beachten  
Delim = ";"  
FeldNr = 60
Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Ein).ReadAll, vbCrLf)
For i = 1 To UBound(Zeilen)
   If Trim(Zeilen(i)) <> "" Then fso.CopyFile Quelle & Replace(Split(Zeilen(i), Delim)(FeldNr - 1), """", ""), Ziel  
Next
Grüße
bastla
jeb-the-batcher
jeb-the-batcher 01.03.2012 um 11:52:15 Uhr
Goto Top
Hallo,

da mische ich mich doch auch noch mal ein...

Zitat von @pieh-ejdsch:
for /f usebackqDelims^=^ eol^= %%s in ("datei.csv") do ( ....

Jetzt ist EOL aber ein Space, es ist dann deaktivert, aber nur weil delims auch noch auf space und TAB steht.
Und die Regel ist wenn das EOL-Zeichen auch ein Delim-Zeichen ist, ist die EOL-Funktion deaktiviert.

Wenn man aber keine Delims haben möchte, braucht man
for /f ^"usebackqDelims^=^ eol^=^  

delims=^" %%s in ("datei.csv") do ( ....  

Dann steht das EOL-Zeichen auf Linefeed, das Zeichen kann aber selbst niemals in einer FOR /F Loop auftauchen.

Gruß
jeb
chrislm
chrislm 01.03.2012 um 12:17:38 Uhr
Goto Top
Also danke an alle, ich habe es so wie ich es wollte, vielen dank für die Mühe!!!
pieh-ejdsch
pieh-ejdsch 01.03.2012 um 19:10:28 Uhr
Goto Top
moin Jeb,

Zitat von @jeb-the-batcher:
> for /f usebackqDelims^=^ eol^= %%s in ("datei.csv") do ( ....
Jetzt ist EOL aber ein Space, es ist dann deaktivert, aber nur weil delims auch noch auf space und TAB steht.
Und die Regel ist wenn das EOL-Zeichen auch ein Delim-Zeichen ist, ist die EOL-Funktion deaktiviert.

Na dann schau nochmal genau auf die Zeile, der Delimiter wird doch auf nichts gesetzt. Das Nichtmaskierte Leerzeichen Vor der For-Variable %%s ist für die Abgrenzung zu den FOR-Optionen.

@set Prompt=$g
echo on
(
echo(
@echo Die obere Schleife ist nur zum nachvollziehen
echo(
echo 1. Kein EOL:
rem 1.
for /f tokens^=1-2Delims^=^,eol^= %%i in ("  .  .") do @echo _%%i_%%j_  
echo(
echo 2. Wenn Hier EOL ein Leerzeichem waere,
echo wuerde die Ausgabe auch ohne Leerzeichen sein
rem 2.
for /f tokens^=1-2Delims^=^,^ eol^= %%i in ("  .  .") do @echo _%%i_%%j_  
echo(
echo 3. so wie hier
rem 3.
for /f "tokens=1-2eol= Delims=, " %%i in ("  .   .") do @echo _%%i_%%j_  
echo(
pause
)3>&1

also kannst Dein LF Konstrukt gleich mit dem anderen (Kein EOL) ersetzen. (obwohl Deins hat was, ich mache mir mittlerweile auch multiple Batcheszeilen)
"C:\Windows\sleep.exe" 1 2>nul >&2 && set "Warte=2>nul >&2 "C:\Windows\sleep.exe" "^  
 || (timeout 2>&1) |find "FEHLER:" >nul && set "Warte=2>nul >&2 Timeout /NOBREAK /T "^  
 || (waitfor 2>&1) |find "FEHLER:" >nul && set "Warte=2>nul >&2 Waitfor x /T "^  
 || set "Warte=2>nul >&2 ping localhost -n "  

set ErrorOut= /c:"Syntaxfehler." ^  
 /c:"Datei .* nicht gefunden"  

Gruß Phil