Batch - Mehrere CSV Dateien in einer for /f durchsuchen?

clemensw  22.04.2022, 17:52

Warum schreibst Du die Daten in CSVs und verwendest keine (relationale) Datenbank?

Strumpfhouse 
Beitragsersteller
 22.04.2022, 18:20

wie würde ich soetwas denn lösen?

1 Antwort

Weshalb nimmst Du an das nur 4 Felder möglich wären.

In meinen Demos verwende ich nur 4 Felder weil das für mich als Demo irgendwo einleuchtend sein sollte.

nach so langer Zeit solltest Du Dich mal mit dem For/f-Befehl beschäftigt haben.

Theoretisch könnte ich auch 1000 Felder Auflösen... (allerdings ist die Zeilenlänge in Batch auf 8000zeichen begrenzt).

Auf normalem Wege kannst du in einem for/f 26Token (%%a bis %%z) auflösen (soviel, wie du Buchstaben in einer Abfolge hast (sonderzeichen-Zauberei lass ich mal außen vor)

demo.csv

Artikel 1 Feld 1,Artikel 1 Feld 2,Artikel 1 Feld 3,Artikel 1 Feld 4,Artikel 1 Feld 5,Artikel 1 Feld 6,Artikel 1 Feld 7,Artikel 1 Feld 8,Artikel 1 Feld 9,Artikel 1 Feld 10,Artikel 1 Feld 11,Artikel 1 Feld 12,Artikel 1 Feld 13,Artikel 1 Feld 14,Artikel 1 Feld 15,Artikel 1 Feld 16,Artikel 1 Feld 17,Artikel 1 Feld 18,Artikel 1 Feld 19,Artikel 1 Feld 20,Artikel 1 Feld 21,Artikel 1 Feld 22,Artikel 1 Feld 23,Artikel 1 Feld 24,Artikel 1 Feld 25,Artikel 1 Feld 26,Artikel 1 Feld 27,Artikel 1 Feld 28,Artikel 1 Feld 29,Artikel 1 Feld 30,Artikel 1 Feld 31,Artikel 1 Feld 32,Artikel 1 Feld 33,Artikel 1 Feld 34,Artikel 1 Feld 35,Artikel 1 Feld 36,Artikel 1 Feld 37,Artikel 1 Feld 38,Artikel 1 Feld 39,Artikel 1 Feld 40,Artikel 1 Feld 41,Artikel 1 Feld 42,Artikel 1 Feld 43,Artikel 1 Feld 44,Artikel 1 Feld 45,Artikel 1 Feld 46,Artikel 1 Feld 47,Artikel 1 Feld 48,Artikel 1 Feld 49,Artikel 1 Feld 50,Artikel 1 Feld 51,Artikel 1 Feld 52,Artikel 1 Feld 53,Artikel 1 Feld 54,Artikel 1 Feld 55,Artikel 1 Feld 56,Artikel 1 Feld 57,Artikel 1 Feld 58,Artikel 1 Feld 59,Artikel 1 Feld 60,Artikel 1 Feld 61,Artikel 1 Feld 62,Artikel 1 Feld 63,Artikel 1 Feld 64,Artikel 1 Feld 65,Artikel 1 Feld 66,Artikel 1 Feld 67,Artikel 1 Feld 68,Artikel 1 Feld 69,Artikel 1 Feld 70,Artikel 1 Feld 71,Artikel 1 Feld 72,Artikel 1 Feld 73,Artikel 1 Feld 74,Artikel 1 Feld 75,Artikel 1 Feld 76,Artikel 1 Feld 77,Artikel 1 Feld 78,Artikel 1 Feld 79,Artikel 1 Feld 80,Artikel 1 Feld 81,Artikel 1 Feld 82,Artikel 1 Feld 83,Artikel 1 Feld 84,Artikel 1 Feld 85,Artikel 1 Feld 86,Artikel 1 Feld 87,Artikel 1 Feld 88,Artikel 1 Feld 89,Artikel 1 Feld 90,Artikel 1 Feld 91,Artikel 1 Feld 92,Artikel 1 Feld 93,Artikel 1 Feld 94,Artikel 1 Feld 95,Artikel 1 Feld 96,Artikel 1 Feld 97,Artikel 1 Feld 98,Artikel 1 Feld 99,Artikel 1 Feld 100
Artikel 2 Feld 1,Artikel 2 Feld 2,Artikel 2 Feld 3,Artikel 2 Feld 4,Artikel 2 Feld 5,Artikel 2 Feld 6,Artikel 2 Feld 7,Artikel 2 Feld 8,Artikel 2 Feld 9,Artikel 2 Feld 10,Artikel 2 Feld 11,Artikel 2 Feld 12,Artikel 2 Feld 13,Artikel 2 Feld 14,Artikel 2 Feld 15,Artikel 2 Feld 16,Artikel 2 Feld 17,Artikel 2 Feld 18,Artikel 2 Feld 19,Artikel 2 Feld 20,Artikel 2 Feld 21,Artikel 2 Feld 22,Artikel 2 Feld 23,Artikel 2 Feld 24,Artikel 2 Feld 25,Artikel 2 Feld 26,Artikel 2 Feld 27,Artikel 2 Feld 28,Artikel 2 Feld 29,Artikel 2 Feld 30,Artikel 2 Feld 31,Artikel 2 Feld 32,Artikel 2 Feld 33,Artikel 2 Feld 34,Artikel 2 Feld 35,Artikel 2 Feld 36,Artikel 2 Feld 37,Artikel 2 Feld 38,Artikel 2 Feld 39,Artikel 2 Feld 40,Artikel 2 Feld 41,Artikel 2 Feld 42,Artikel 2 Feld 43,Artikel 2 Feld 44,Artikel 2 Feld 45,Artikel 2 Feld 46,Artikel 2 Feld 47,Artikel 2 Feld 48,Artikel 2 Feld 49,Artikel 2 Feld 50,Artikel 2 Feld 51,Artikel 2 Feld 52,Artikel 2 Feld 53,Artikel 2 Feld 54,Artikel 2 Feld 55,Artikel 2 Feld 56,Artikel 2 Feld 57,Artikel 2 Feld 58,Artikel 2 Feld 59,Artikel 2 Feld 60,Artikel 2 Feld 61,Artikel 2 Feld 62,Artikel 2 Feld 63,Artikel 2 Feld 64,Artikel 2 Feld 65,Artikel 2 Feld 66,Artikel 2 Feld 67,Artikel 2 Feld 68,Artikel 2 Feld 69,Artikel 2 Feld 70,Artikel 2 Feld 71,Artikel 2 Feld 72,Artikel 2 Feld 73,Artikel 2 Feld 74,Artikel 2 Feld 75,Artikel 2 Feld 76,Artikel 2 Feld 77,Artikel 2 Feld 78,Artikel 2 Feld 79,Artikel 2 Feld 80,Artikel 2 Feld 81,Artikel 2 Feld 82,Artikel 2 Feld 83,Artikel 2 Feld 84,Artikel 2 Feld 85,Artikel 2 Feld 86,Artikel 2 Feld 87,Artikel 2 Feld 88,Artikel 2 Feld 89,Artikel 2 Feld 90,Artikel 2 Feld 91,Artikel 2 Feld 92,Artikel 2 Feld 93,Artikel 2 Feld 94,Artikel 2 Feld 95,Artikel 2 Feld 96,Artikel 2 Feld 97,Artikel 2 Feld 98,Artikel 2 Feld 99,Artikel 2 Feld 100

26TokenDemo.cmd

@echo off
for /f "usebackq tokens=1-26 delims=," %%a in ("demo.csv") do (
   echo   1.Token=%%a
   echo usw alle kleien buchstaben  %%%% b bis y 
   echo  26.Token=%%z
   echo:
   echo naechste csv-Zeile:
)
pause

brauchst Du mehr Felder, kannst du mit dem "Rest-Token"(*) alles was nicht am Stück greifbar ist dem letzten Token zuweisen . ...und dieses in einem inneren for/f auflösen (da hast Du auch noch die 26 Großbuchstaben zur Verfügung)

51TokenDemo.cmd

@echo off
  rem 25token und Rest (der  wird in %%z übergeben)
for /f "usebackq tokens=1-25* delims=," %%a in ("demo.csv") do (
      rem der  wird in %%z weitergereicht :)
    for /f "tokens=1-26 delims=," %%A in ("%%z") do (
        echo   1.Token=%%a
        echo  25.Token=%%y
        echo  26.Token=%%A
        echo  51.Token=%%Z
    )
    echo:
    echo naechste csv-Zeile:
)
pause

...damit haben wir noch immer nicht die 100 in unserem Super-CSV geknackt.

Die Buchstaben sind uns ausgegangen 😭(den Sonderzeichen-Kack wollen wir vermeiden)

Aber wenn wir wieder den Rest mit einer Variable an eine Subroutine tunneln, haben wir noch mal 51 ... (tunneln, weil das übergeben per Parameter Tücken hat)

moreTokensDemo.cmd

@echo off
  rem 25token und Rest (der  wird in %%z übergeben)
for /f "usebackq tokens=1-25* delims=," %%a in ("demo.csv") do (
      rem der  wird in %%z weitergereicht :)
    for /f "tokens=1-25* delims=," %%A in ("%%z") do (
        echo   1.Token=%%a
        echo  25.Token=%%y
        echo  26.Token=%%A
        echo  50.Token=%%Y
        set "__Rest=%%Z"
        call :extendSplitter
    )
    echo:
    echo naechste csv-Zeile:
)
goto :endSub
:extendSplitter
for /f "tokens=1-25* delims=," %%a in ("%__Rest%") do (
    for /f "tokens=1-25* delims=," %%A in ("%%z") do (
        echo  51.Token=%%a
        echo  75.Token=%%y
        echo  76.Token=%%A
        echo 100.Token=%%Y
          rem theoretisch  könntest Du hier  wieder  den Rest "fangen"
        rem set "__Rest=%%Z"
    )
)
  rem und die ganze Show wieder  und wieder durchexerzieren...
:: for /f "tokens=1-25* delims=," %%a in ("%__Rest%") do (
::    for /f "tokens=1-25* delims=," %%A in ("%%z") do (
::        echo 101.Token=%%a
::        echo 150.Token=%%Y
::        set "__Rest=%%Z" ))

exit /b
:endSub

pause

...und Du glaubst mit 4 wäre Schluss?

Du möchtest mehr Spalten/Zeieln für die Demo?

kannst Du haben...

Ich scheibe ganz sicher soviel nicht von Hand (ich programmiere mir nen Diener:

powershell "1..10|foreach{ $_dummy=$_; (1..200|foreach{'Artikel {0} Feld {1}' -f $_dummy,$_}) -join ','}|out-file 'demo.csv' -enc ascii"
Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

Strumpfhouse 
Beitragsersteller
 22.04.2022, 22:02

Erzengel.. Du bist ja echt mal der Wahnsinn :D
Sobald ich dieses Script fertig habe fange ich an mich mal intensiv mit Powershell zu beschäftigen :D
Ich will dieses Skript nur unbedingt mal fertig kriegen^^
QUasi mein letztes Batch Projekt.

Wie der Zufall es will möchte ich mir einige Daten durch eine Suche aus der .csv Datei anzeigen lassen.

Nun habe ich den Code soweit fertig, mit der Suche nach Barcode, Quantity und Location funktioniert das ganze auch aber ich möchte die Produkte auch nach Namen suchen können. So wie es jetzt ist muss ich aber auch Groß- und Kleinschreibung sowie den vollständigen genauen Namen des Produkts eingeben um ergebnisse zu erhalten. Wie kriege ich das so hin, dass ich bei einem Namen von z.B. "Produktname XY 200ml 1234 Volt 900 Zoll 4k" auch einfach z.B. "XY" oder "1234 Volt" oder "produktname" oder "produkt name" auch die passenden Ergebnisse erhalte?

Auch habe ich momentan auch für die verschiedenen Lagerungsmethoden je eine eigene csv Datei. Ich würde wenn ich die Lagerungsmethode in die 5. Zeile schreibe alle Dateien in einer zusammenfassen. Ich habe eine Funktion, mit der ich mir abgeleitet aus deiner vorherigen Beschreibung alle Artikel anzeigen lassen kann. Wenn es einige dutzend oder hundert Artikel sind scrollt die BAT aber ganz herunter. Gibt es eine möglichkeit sich 1. nur immer 20 Artikel anzeigen zu lassen und dann mit Tastendruck ([N ]Previous Page/ [M] Next Page) die nächsten 20 anzeigen zu lassen und 2. das ganze auch dementsprechend nach Lagerungsmethoden zu filtern? Wobei ich dazu schon ne Idee hätte.. Ich sehe aufjedenfall ein, ass ich mich nicht genug mit einzelnen Funktionen beschäftigt habe, das hole ich gerade intensiv nach. Du musst wissen, ich mache das mit Batch schon irgendwie lange zeit so und es klappt irgendwie immer. Mit Powershell mache ich das grundlegend anders.

0
Strumpfhouse 
Beitragsersteller
 23.04.2022, 00:43

Sag mal, diese Linien, die du in Variablen gepackt hast, ich habe generell mal etwas herumprobiert aber verstehe es nicht. Ich sollte auch so ein Raster bauen aber mit mehr Spalten, kriege das aber nicht hin.

0
Erzesel  23.04.2022, 08:03
@Strumpfhouse

Wenn Du die __UnderLineCharkters meinst , so ist das nur eine Marotte von mir. (wen auch eine sehr nützliche)

Es gibt haufenweise vom System vordefinierte Variablen , hinzukommen normale selbstdefinierte Hauptvariablen.

In letztere muss man (bei großen Scripten) irgendwie ein System bringen.

  • Normale Variablen schreibe ich einfach CamelCaseVariableName.
  • Normale (Pseudo)Strukturen und -Arrays VarName.SubVariable bzw. ArrayName.Index.

Batch kennt keine klaren Variablenzustandigkeiten (Scope). Alle Variablen sind Scriptglobal . Setlocal-Endlocal wäre in den meisten Fällen überdimensioniert...

Verwende ich Codeelemente die ich mir aus anderen Projekten einfach zusammenkopiere, muss ich schlau sein, den diese könnten mit bestehenden Variablen in Konflikt geraden... da kommt "mein" __var ins Spiel

Der __ signalisiert mir einfach, das diese Variable nicht normal ist.

Meist handelt sich um eine Temporäre Variable, welche nicht mit den "Normalen" zusammenstoßen soll. (achtung! %temp% , %tmp% sind Systempfade! können nicht als Wegwerfvariable dienen) eine totale WegwerfVariable ist bei mir %__dummy%, da weiß ich genau, wenn ich den aktuellen Codeablauf verlasse ist deren Inhalt nicht mehr vertrauenswürdig.

Oben dem %__Rest% ist in diesem Sinne auch nur solange zu vertrauen, wie man die Variable im Auge behält und Dann vergessen...

Will ich den Inhalt mehrerer variable während eines Ablaufs beobachten, ist der __undeline am beginn auch prima.

set "anfangsbuchstaben" zeigt alle Variablen an, welche gleich beginnen

set "__" zeigt alle Variablen, welche mit __ beginnen. (eine Art von schnelle Debuginformation)

set "Irgendwas=blubb"
set "__dummy=0"
set "__WasAnderes=Ratzfatz"
  rem  zeige  nur  die Variblen  mit __ am anfang
set "__" 
::set ""   zeigt alle Variablen
pause

__@.VariableName... vewende ich gern, um viele gleichnamige Variablen auf eine rutsch in ein Datei zu speichern, zu löschen ...usw

set "__@.User1.Name=Franz"
set "__@.User1.Age=48"
set "__@.User2.Name=Erna"
set "__@.User2.Age=93"
 rem alle __@. in Datei speichern
set "__@." > "users.cfg"
 rem alle __@. löschen
for /f "delims==" %%a in ('set "__@."') do (set "%%a=")
set "__@."
 rem alle aus Datei lesen
for /f "usebackq tokens=*" %%a in ("users.cfg") do (set "%%a")
set "__@."
pause

...also ist "__" einfach meine Art, Herr über das Chaos zu bleiben. Und wird schnell Chaotisch.


0