haberl92
Goto Top

CMD zum Auslesen aus .txt als Variable zum Dateien verwalten

Hallo zusammen,
ich bin neu hier.
Ich bin gerade dabei eine Batch-Datei(cmd) zu schreiben, welche eine .txt-Datei ausliest und aufsplittet.
Der Text sieht ungefähr so aus:

Statistik:
Sortfach 1 (Bayern): 25558 Daten
188310400
Sortfach 2 (NRW): 24850 Daten
184940005
Sortfach 3 (Sachsen): 0 Daten
Sortfach 4 (NRW): 12930 Daten
183411401
Sortfach 5 (Bayern): 8449 Daten
184212505
Sortfach 6 (Berlin): 20383 Daten
182171012
188030775
187202793
185830517
185230076
188035612
186431652
183170002
188036123
(das geht bis Sortfach 21)

Nun ist es so, dass ich parallell zu der Text-Datei einen Ordner mit PDF bekomme, welche ich sortieren muss.
Die PDF haben die 9-stelligen Zahlen im Dateinamen.
Am besten sollen sie in Ordner verteilt werden (Ordnername: Sortfach 1, Sortfach 2, usw.)
Das Problem ist, dass ich diese Statistik jeden Monat bekomme und es nicht immer gleich viele Zahlen bei einem "Sortfach" sind.

Ich habe schon sehr viel probiert, jedoch immer gescheitert.
Ich hoffe, Ihr könnt mir weiterhelfen.

Content-ID: 846256428

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

Ausgedruckt am: 25.11.2024 um 11:11 Uhr

148656
148656 28.06.2021 um 22:56:46 Uhr
Goto Top
Moin,
Warum ein Batch-Script und keine Powershell?

Gruß
C.C.
Haberl92
Haberl92 28.06.2021 um 23:02:07 Uhr
Goto Top
Mit Powershell kenn ich mich noch gar nicht aus. Aber wenn es damit umsetzbar wäre, warum nicht.
148656
148656 29.06.2021 um 08:49:33 Uhr
Goto Top
Moin,

Naklar, ist dies mit Powershell problemlos umsetzbar. @colinardo hat für Anfänger ein Übersicht zusammengefasst. Über die Suche (rechts oben) findest du Scripte, die du nur noch anpassen müsstest.

Aber da du bereits Arbeit in das Batch-Script investiert hast, zeig doch mal was du schon hast.

Gruß
C.C.
Haberl92
Haberl92 29.06.2021 um 10:21:20 Uhr
Goto Top
Moin moin,

ich habe es auf verschiedenen Wegen versucht, aber alles wieder verworfen, da nichts wirklich funktioniert hat.

z.B. habe ich eine Eingabeaufforderung versucht, welche ich die Zeilennummer eingeben musste, ab wann er auslesen soll und dann mit "+1" hochzählen lassen, Jedoch habe ich es zuerst nur mit echo>.txt in eine seperate Datei schreiben lassen, aber da hat er mir immer nur die letzte Zahl ausgegeben.

Also bin ich ganz am Anfang und wäre über einen Code für andere Skripte auch sehr dankbar
148656
148656 29.06.2021 um 11:18:20 Uhr
Goto Top
Zitat von @Haberl92:

Hallo zusammen,
ich bin neu hier.
Ich bin gerade dabei eine Batch-Datei(cmd) zu schreiben, welche eine .txt-Datei ausliest und aufsplittet.
Der Text sieht ungefähr so aus:

Statistik:
Sortfach 1 (Bayern): 25558 Daten
> 188310400
> Sortfach 2 (NRW): 24850 Daten
> 184940005
> Sortfach 3 (Sachsen): 0 Daten
> Sortfach 4 (NRW): 12930 Daten
> 183411401
> Sortfach 5 (Bayern): 8449 Daten
> 184212505
> Sortfach 6 (Berlin): 20383 Daten
> 182171012
> 188030775
> 187202793
> 185830517
> 185230076
> 188035612
> 186431652
> 183170002
> 188036123
(das geht bis Sortfach 21)

Nun ist es so, dass ich parallell zu der Text-Datei einen Ordner mit PDF bekomme, welche ich sortieren muss.
Die PDF haben die 9-stelligen Zahlen im Dateinamen.
Am besten sollen sie in Ordner verteilt werden (Ordnername: Sortfach 1, Sortfach 2, usw.)
Das Problem ist, dass ich diese Statistik jeden Monat bekomme und es nicht immer gleich viele Zahlen bei einem "Sortfach" sind.

Ich habe schon sehr viel probiert, jedoch immer gescheitert.
Ich hoffe, Ihr könnt mir weiterhelfen.
Dann ist auch hierfür die Suche brauchbar. Deine Frage wird regelmäßig, im gleichen Wortlaut Gestell und beantwortet.

Alternativ kannst du meine Antwort melden und ein Moderator wird sich deinem Problem annehmen.

Gruß
C.C.
Haberl92
Haberl92 29.06.2021 um 11:24:57 Uhr
Goto Top
Ich habe das Forum hier schon durchsucht und auch andere Foren.
Habe auch vieles gefunden, jedoch war es auf meinen Fall nur bedingt umsetzbar.
colinardo
Lösung colinardo 29.06.2021 aktualisiert um 11:52:56 Uhr
Goto Top
Servus @Haberl92 , willkommen auf Administrator.de!
Zitat von @Haberl92:
Also bin ich ganz am Anfang und wäre über einen Code für andere Skripte auch sehr dankbar
Gerne, damit kann ich dienen. Hiermit kannst du das gewünschte z.B. mittels Powershell erreichen.
(Kommentare zu den Zeilen siehe Code)
# Textdatei mit der Nummernzuordnung
$datafile = 'D:\Data\data.txt'  
# Ordner mit den PDF-Dateien
$datadirectory = 'D:\Data\pdfs'  
# Textdatei in ein PSCustomObject einlesen um Zuordnung zu vereinfachen
$sortkeys = [regex]::matches((gc $datafile -raw),'(?ism)(^Sortfach \d+).*?$(.*?)(?=^Sortfach|\Z)').Captures | %{[pscustomobject]@{Sortfach=$_.Groups[1].Value;Numbers=$_.Groups[2].Value}}  
# Alle PDF-Dateien nach der Nummer im Basename der Datei sortieren und den Sortfach-Ordnern zuordnen
ls $datadirectory -File -Filter *.pdf -PipelineVariable f | group {$sortkeys | ?{$_.Numbers -match [regex]::match($f.Basename,'\d{9}').Value} | select -Expand Sortfach} | ?{$_.Name -ne ''} | %{  
    # Dateien der Gruppe in den neuen Zielordner verschieben
    $_.Group | move-item -Destination (md (join-path $datadirectory $_.Name) -Force).FullName -Verbose
}

[OT]
@148656
Ich bitte dich höflichst um mehr Engagement statt hier in den Posts nur heiße Luft zu verbreiten. Solche Posts machen ein Forum letztendlich kaputt. Würdest du bswp. auf StackOverflow nur solche "Lehrer-Antworten" finden wäre es nicht so erfolgreich geworden. Danke!
[/OT]

Grüße Uwe
Haberl92
Haberl92 29.06.2021 aktualisiert um 12:19:09 Uhr
Goto Top
Zitat von @colinardo:

Servus @Haberl92 , willkommen auf Administrator.de!
Zitat von @Haberl92:
Also bin ich ganz am Anfang und wäre über einen Code für andere Skripte auch sehr dankbar
Gerne, damit kann ich dienen. Hiermit kannst du das gewünschte z.B. mittels Powershell erreichen.
(Kommentare zu den Zeilen siehe Code)
> # Textdatei mit der Nummernzuordnung
> $datafile = 'D:\Data\data.txt'  
> # Ordner mit den PDF-Dateien
> $datadirectory = 'D:\Data\pdfs'  
> # Textdatei in ein PSCustomObject einlesen um Zuordnung zu vereinfachen
> $sortkeys = [regex]::matches((gc $datafile -raw),'(?ism)(^Sortfach \d+).*?$(.*?)(?=^Sortfach|\Z)').Captures | %{[pscustomobject]@{Sortfach=$_.Groups[1].Value;Numbers=$_.Groups[2].Value}}  
> # Alle PDF-Dateien nach der Nummer im Basename der Datei sortieren und den Sortfach-Ordnern zuordnen
> ls $datadirectory -File -Filter *.pdf -PipelineVariable f | group {$sortkeys | ?{$_.Numbers -match [regex]::match($f.Basename,'\d{9}').Value} | select -Expand Sortfach} | ?{$_.Name -ne ''} | %{  
>     # Dateien der Gruppe in den neuen Zielordner verschieben
>     $_.Group | move-item -Destination (md (join-path $datadirectory $_.Name) -Force).FullName -Verbose
> }
> 


Vielen Dank. Ich werde das heute nachmittag gleich mal testen und schauen, ob ich es mit Powershell hin bekomme.
Werde mich dann abends wieder melden.

Gleich noch eine Frage vorweg:
Die PDFs haben die Nummer am Anfang des Dateinamen, das bedeutet, dass noch andere Buchstaben und Zahlen im Namen stehen.
Funktioniert das damit auch?

Ich könnte zur Not den Dateinamen mittels CMD-Batch auf die eigentliche Nummer kürzen lassen
148656
148656 29.06.2021 aktualisiert um 14:21:19 Uhr
Goto Top
[OT]
Lieber @colinardo,

ich nehme deine Kritik gern zur Kenntnis und Verweise auf die letzte Diskussion diesbezüglich.
Selbst auf StackOverflow.com werden User die mit nichts anderem, als dem frommen Wunsch "Ein andere möge meinen Arbeit machen." kommen, auf Anleitungen sowie ähnliche Beiträge innerhalb des Forums verwiesen. StackOverflow.org ist da etwas überschaubarer. Deine Definition von "Engagement" sollte man in einem gesonderten Thread erörtern. Einem Anfänger die Lösung in Form von "One-Liners" zu kredenzen, macht es dem lernwilligem Einsteiger nicht Einfacher oder Verständlicher.

Gruß
C.C.
[/OT]
colinardo
colinardo 29.06.2021 aktualisiert um 15:28:18 Uhr
Goto Top
Zitat von @Haberl92:
Gleich noch eine Frage vorweg:
Die PDFs haben die Nummer am Anfang des Dateinamen, das bedeutet, dass noch andere Buchstaben und Zahlen im Namen stehen.
Funktioniert das damit auch?
Ja, dem Code oben ist es egal wo die Nummer im Dateinamen steht, er findet sie dank Regular Expressions in diesem Abschnitt automatisch.
[regex]::match($f.Basename,'\d{9}').Value
Bedeutet im Klartext: Finde eine 9-stellige Ziffernfolge im Basename des Dateinamens egal wo diese dort zu finden ist.
colinardo
colinardo 29.06.2021 aktualisiert um 15:41:12 Uhr
Goto Top
[OT]
Zitat von @148656:
Selbst auf StackOverflow.com werden User die mit nichts anderem, als dem frommen Wunsch "Ein andere möge meinen Arbeit machen." kommen,
Aber eher selten.
Wir sind hier zu helfen, und nicht die "Arbeit anderer zu machen". Man sollte das nicht jedem unterstellen der hier eine Frage stellt. Sicher gibt es die ein oder anderen User die das ausnutzen, aber was kümmert mich das, ich antworte hier nicht primär nur dem "einen" User der die Frage selbst stellt, sondern stelle hier eine Lösung öffentlich ein die auch für x andere User die hier vorbei schauen eine Hilfestellung sein kann.

Einem Anfänger die Lösung in Form von "One-Liners" zu kredenzen, macht es dem lernwilligem Einsteiger nicht Einfacher oder Verständlicher.
Deswegen muss man hier nicht auf produktiven Input verzichten der sich dem explizit dem Thema widmet statt einen User dauernd nur mit Phrasen ala "Benutze doch bitte unsere Suche, da wird dir geholfen" zu bombardieren. Solche Threads schaut sich hinterher kaum einer mehr an und schreckt andere User hier nur ab. Das ist übrigens auch in unseren Diskussionsrichtlinien so hinterlegt.
[/OT]
Haberl92
Haberl92 29.06.2021 um 16:34:52 Uhr
Goto Top
Zitat von @colinardo:

Zitat von @Haberl92:
Gleich noch eine Frage vorweg:
Die PDFs haben die Nummer am Anfang des Dateinamen, das bedeutet, dass noch andere Buchstaben und Zahlen im Namen stehen.
Funktioniert das damit auch?
Ja, dem Code oben ist es egal wo die Nummer im Dateinamen steht, er findet sie dank Regular Expressions in diesem Abschnitt automatisch.
> [regex]::match($f.Basename,'\d{9}').Value
> 
Bedeutet im Klartext: Finde eine 9-stellige Ziffernfolge im Basename des Dateinamens egal wo diese dort zu finden ist.

Der Code funktioniert perfekt. Vielen Dank.

Nun noch eine Frage:
Kann ich in den Code noch eine Variable setzen im Dateipfad?
Die Variable müsste ich dann bei jedem Ausführen selber eingeben.

Tut mir leid, wenn ich so viel frage, aber bei Powershell bin ich ein kompletter Noob.
colinardo
colinardo 29.06.2021 aktualisiert um 16:59:03 Uhr
Goto Top
Zitat von @Haberl92:
Nun noch eine Frage:
Kann ich in den Code noch eine Variable setzen im Dateipfad?
Die Variable müsste ich dann bei jedem Ausführen selber eingeben.

Ja kein Problem, z.B.
$var = Read-Host "Deine Eingabe bitte"  
$datadirectory = "d:\Pfad\$var"  
oder dem Skript über Parameter den Wert mitgeben.
Dazu im Kopf des Skripts den Parameter definieren
param(
    [String]$var
)
$datadirectory = "d:\Pfad\$var"  
Und dem Skript den Wert
dann über die Komandozeile mitgeben
.\script.ps1 -var 'Dein Wert'  
Haberl92
Haberl92 29.06.2021 um 18:06:50 Uhr
Goto Top
Das funktioniert bei mir leider nicht.
Ich kann zwar die Variable eingeben aber er nutzt sie nicht im Pfad.

$var = Read-Host "Nummer eingeben"  
$datafile = 'P:\test\sortierung\$var\$var_Report.txt'  
$datadirectory = 'P:\test\rechnungen\$var'  
$sortkeys = [regex]::matches((gc $datafile -raw),'(?ism)(^Sortfach \d+).*?$(.*?)(?=^Sortfach|\Z)').Captures | %{[pscustomobject]@{Vorsortfach=$_.Groups[1].Value;Numbers=$_.Groups[2].Value}}  
ls $datadirectory -File -Filter *.pdf -PipelineVariable f | group {$sortkeys | ?{$_.Numbers -match [regex]::match($f.Basename,'\d{9}').Value} | select -Expand Sortfach} | ?{$_.Name -ne ''} | %{  
$_.Group | move-item -Destination (md (join-path $datadirectory $_.Name) -Force).FullName -Verbose
}


Was mache ich falsch?
Kann es sein, weil die Variabel ein Ordnername ist und Teil des Dateinamen der TXT Datei, dass es dadurch Probleme macht?
colinardo
colinardo 29.06.2021 aktualisiert um 18:52:25 Uhr
Goto Top
Du musst bei Variablen innerhalb von Strings normale Anführungszeichen statt Hochkommas verwenden, denn nur innerhalb von normalen Anführungszeichen werden Variablen geparst!
Außerdem musst du wenn Strings auf die Variable folgen die gültige Zeichen einer Variablen sind die Variable mit ${} kappseln
$var = Read-Host "Nummer eingeben"  
$datafile = "P:\test\sortierung\$var\${var}_Report.txt"  
$datadirectory = "P:\test\rechnungen\$var"  
Haberl92
Haberl92 29.06.2021 aktualisiert um 18:42:20 Uhr
Goto Top
Zitat von @colinardo:

Und dem Skript den Wert
dann über die Komandozeile mitgeben
> .\script.ps1 -var 'Dein Wert'  
> 

was meinst du damit?
Ich habe nun die Variable in {} gesetzt, jedoch scheint es so, dass er nicht mal den Ordnernamen durch die Variable ersetzt.

Powershell sagt nur, dass der Pfad nicht gefunden wird und zeigt mir den Pfad mit "$var" anstelle der eingegebenen Variable
colinardo
colinardo 29.06.2021 aktualisiert um 19:03:51 Uhr
Goto Top
Zitat von @colinardo:

Und dem Skript den Wert
dann über die Komandozeile mitgeben
>> .\script.ps1 -var 'Dein Wert'  
>> 

was meinst du damit?

Du verwechselst hier was, das zweite war eine alternative Variante und hat nichts mit der ersten zu tun!
Lies bitte mein letztes Kommentar ganz genau! Dann verstehst du warum es bei dir nicht funktioniert. Du verwendest Hochkommas statt Anführungszeichen deswegen wird die Variable innerhalb des Strings nicht aufgelöst.

Also:
$var = Read-Host "Nummer eingeben"  
$datafile = "P:\test\sortierung\$var\${var}_Report.txt"  
$datadirectory = "P:\test\rechnungen\$var"  

Hier kannst du das übrigens auch nachlesen
Variable expansion in strings and here-strings

Strings mit Hochkommas verwendet man nur dann wenn man nicht möchte das spezielle Zeichen anders darin interpretiert werden. Das mache ich grundsätzlich immer wenn ich darin keine Variablen oder Subexpressions verwende, denn es könnte ja sein das der User da Zeichen einsetzt die die Powershell ansonsten anders interpretiert.
148656
148656 29.06.2021 um 19:04:31 Uhr
Goto Top
So, da das Problem vom TO gelöst ist.
[OT]
@colinardo kannst Du dich bitte entscheiden was Du willst?
Mal soll es für den Anfänger sein, dann lieferst DU Input für den semiprofessionellen Fortgeschrittenen und der Profi geht leer aus.
Ich hatte den TO gefragt, muss es wirklich Batch sein.
Nach seiner Antwort, habe ich ihn auf deinen Beitrag verwiesen und ihm den Tipp für die SuFu gegeben.
Wenn sich der TO wirklich mit dem Thema befasst hätte, würde man mindestens einen Tag nichts von ihm hören. Da er sich mit den Links und dessen Inhalt beschäftigt.
Auf den Hinweis, er möge das Posten was er bereits erarbeitet hat, kam die Default-Antwort. Was soll ich hiervon halten. In den letzten 3 Tagen haben DU und @em-pie in anderen Fragen zum Thema "Powershell und Batch" mehrfach gezeigt, wie Daten aus einem Textfile eingelesen und verarbeitet werden.
Ich bin der Letzte, der einen Kollegen hängen lässt aber wie soll man einem Kollegen nachhaltig helfen, der keine (Internen)Links lesen will. Muss man jedes Mal erst nachfragen, "Was machst du, wenn das Script mitten in der Nacht abändert werden muss, um Schaden von der Firma oder vom Kunden fernzuhalten?".
Kommen wir zum Profi, der auf der Strecke bleibt. Strukturierte Ausnahmebehandlung kennst Du sicherlich? Warum fehlt dies immer in deinen "Skripten"?

Gruß
Case Closed
[/OT]
Haberl92
Haberl92 29.06.2021 um 19:05:57 Uhr
Goto Top
Tut mir leid, dass mit den Anführungszeichen habe ich irgendwie überlesen.
Jetzt funktioniert es perfekt.

Vielen vielen Dank
Haberl92
Haberl92 29.06.2021 um 19:17:50 Uhr
Goto Top
@148656
Ich wollte hauptsächlich eigentlich einen Lösungsvorschlag für einen CMD-Batch.
Da ich mich damit ein wenig mehr auskenne.
Aber die Lösung des Problems war mir in dem Fall wichtiger, dadurch war ich offen für andere Skripte.
Weil ich jedoch mit Powershell selten bis nie gearbeitet habe, bin ich sehr dankbar, dass es Personen gibt, die mir helfen, das Problem schnellstmöglich zu erledigen, auch wenn ich den Code hauptsächlich abgeschrieben habe.
Ist ja auch klar ohne Kenntnisse mit Powershell.
Und ich habe von meinen Versuch es mit CMD zu lösen, wirklich alles wieder gelöscht, da ich auf keine Lösung gekommen bin, also konnte ich auch nichts posten.
Oder hätte ich es nochmal schreiben sollen, dass mir dann gesagt wird, dass es nicht funktioniert.
Die SuFu hab ich benutzt, jedoch nur für CMD, aber wie gesagt, nichts passendes für meinen Fall.
Und nach Powershell habe ich mit der SuFu nicht gesucht. Auch wenn doch, hätte ich durch lesen und lernen keine Ahnung wie lange gebraucht.

Also für mich, war das die perfekte Lösung von @colinardo
Nochmals vielen vielen Dank!!!
Haberl92
Haberl92 30.06.2021 um 17:54:27 Uhr
Goto Top
Nun habe ich noch eine letzte Frage:
Das Skript funktioniert wunderbar, aber sollte es sich nicht automatisch schließen nach Fertigstellung?
Ich habe auch schon versucht "Exit" dazu zu schreiben, aber gleiches Ergebnis.
Ich habe beim recherchieren im Netz irgendwas mit"NoExit" gefunden.
Kann es sein, dass dies irgendwo im Skript versteckt drin steht?