Mehrere Dateien in einer Textdatei per batch oder script zusammenführen
Guten Tag in die Runde der Fachleute.
Ich habe folgendes Problem:
In einem Unterordner liegen Dateien mit verschiedenen Dateinamen z.B. 12345678_0300_1_ra_123_yyy.txt, 12345678_0320_1_ra_123_yyy.txt, 12345678_0340_1_ra_123_yyy.txt usw. Alle Dateien mit dem Dateinameninhalt 0300 sollen erkannt und in eine Datei (12345678_0300_1_rco_123_yyy.txt) geschrieben werden. Das Gleiche ist auch auf die restlichen Dateien (0320, 0340, 0360, 0380, 0400, 0420, 0440, 0460, 0480, usw.) anzuwenden. Der erste Block des Dateinamens (z.B. 12345678) kann unterschiedlich lang sein, hat aber immer gleiche Bezeichnung in dem Dateiordner. Die Angabe im zweiten Block kann variieren z.B 0320, 0321......0340, 0341 usw. Er besteht immer aus vier Ziffern. Die restlichen Blöcke sind immer gleich.
Ziel ist es, die Dateien mit der selben Bezeichnung im Block zwei, zu einer Datei zusammenzuführen und alle Punkte in der neuen Datei mit einem Komma zu ersetzen. Ebenfalls soll der Unterordner (wo die zu bearbeitenden Dateien liegen) variabel ausgesucht werden können z.B. c:\Ordnerx\Unterordner\Dateien, d:\Ordnery\Unterordner\Dateien.
Für Eure Bemühungen im Voraus vielen Dank.
Hausboot
Ich habe folgendes Problem:
In einem Unterordner liegen Dateien mit verschiedenen Dateinamen z.B. 12345678_0300_1_ra_123_yyy.txt, 12345678_0320_1_ra_123_yyy.txt, 12345678_0340_1_ra_123_yyy.txt usw. Alle Dateien mit dem Dateinameninhalt 0300 sollen erkannt und in eine Datei (12345678_0300_1_rco_123_yyy.txt) geschrieben werden. Das Gleiche ist auch auf die restlichen Dateien (0320, 0340, 0360, 0380, 0400, 0420, 0440, 0460, 0480, usw.) anzuwenden. Der erste Block des Dateinamens (z.B. 12345678) kann unterschiedlich lang sein, hat aber immer gleiche Bezeichnung in dem Dateiordner. Die Angabe im zweiten Block kann variieren z.B 0320, 0321......0340, 0341 usw. Er besteht immer aus vier Ziffern. Die restlichen Blöcke sind immer gleich.
Ziel ist es, die Dateien mit der selben Bezeichnung im Block zwei, zu einer Datei zusammenzuführen und alle Punkte in der neuen Datei mit einem Komma zu ersetzen. Ebenfalls soll der Unterordner (wo die zu bearbeitenden Dateien liegen) variabel ausgesucht werden können z.B. c:\Ordnerx\Unterordner\Dateien, d:\Ordnery\Unterordner\Dateien.
Für Eure Bemühungen im Voraus vielen Dank.
Hausboot
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 250454
Url: https://administrator.de/contentid/250454
Ausgedruckt am: 23.11.2024 um 08:11 Uhr
24 Kommentare
Neuester Kommentar
Hallo,
zum ersten Punkt schon mal:
Dann noch die Zeichen ersetzen - gibt es bestimmt Commandline -Tools wie "sed für Windows" oder hier ( Per Batch ein Wort in Einer Textdatei gegen ein anderes ersetzen ).
Gruß
LS
zum ersten Punkt schon mal:
type *_0300_*.txt > daten_0300.txt
ren daten_0300.txt 12345678_0300_1_rco_123_yyy.txt
Dann noch die Zeichen ersetzen - gibt es bestimmt Commandline -Tools wie "sed für Windows" oder hier ( Per Batch ein Wort in Einer Textdatei gegen ein anderes ersetzen ).
Gruß
LS
na dann halt
ist weniger 'Handarbeit'
@echo off
:: von 320 bis 980 mit Schrittweite 20
for /L %%i IN (320, 20, 980) do call :PROC1 %%i
goto ENDE
:PROC1
set BLK=%1
type *_0%BLK%_*.txt > daten_0%BLK%.txt
ren daten_0%BLK%.txt 12345678_0%BLK%_1_rco_123_yyy.txt
:: tausche die Zeichen in der Datei ...
goto :EOF
:ENDE
ist weniger 'Handarbeit'
Hallo Hausboot,
anhand dieser beiden Aussagen
und den Beispieldateinamen ergibt sich eine Schwierigkeit: Es können nicht mehrere Dateien in dem Verzeichnis existieren, bei denen der zweite Block des Namens gleich ist, da ja schon alle anderen Namensbestandteile gleich sind. Da dem bestimmt nicht so ist (sonst würde Dein Problem nicht existieren), könnte man das jetzt einfach als Missverständnis ignorieren, aber nach welcher Regel wird dann der Name (bzw. der erste Block des Names) der Sammeldatei bestimmt?
Gruß
Friemler
anhand dieser beiden Aussagen
Zitat von @Hausboot:
Der erste Block des Dateinamens (z.B. 12345678) kann unterschiedlich lang sein, hat aber immer gleiche Bezeichnung in dem Dateiordner.
undDer erste Block des Dateinamens (z.B. 12345678) kann unterschiedlich lang sein, hat aber immer gleiche Bezeichnung in dem Dateiordner.
und den Beispieldateinamen ergibt sich eine Schwierigkeit: Es können nicht mehrere Dateien in dem Verzeichnis existieren, bei denen der zweite Block des Namens gleich ist, da ja schon alle anderen Namensbestandteile gleich sind. Da dem bestimmt nicht so ist (sonst würde Dein Problem nicht existieren), könnte man das jetzt einfach als Missverständnis ignorieren, aber nach welcher Regel wird dann der Name (bzw. der erste Block des Names) der Sammeldatei bestimmt?
Gruß
Friemler
Hallo Hausboot,
OK, das ist schon besser, aber noch nicht perfekt:
und
Da Block fünf und sechs variabel sind, müssen sie im Namen der Zieldatei entweder weggelassen werden oder ich benötige eine Bildungsregel für die beiden Blöcke.
Gruß
Friemler
OK, das ist schon besser, aber noch nicht perfekt:
und
Zitat von @Hausboot:
Datei 12345678_0300_1_ra_123_yyy.txt
Dateien sind z.B neun mal vorhanden mit anderen Werten in Block fünf und sechs.
...
Die zusammengefasste Datei soll in
12345678_0300_1_rco_123_yyy.txt ... gespeichert werden.
Datei 12345678_0300_1_ra_123_yyy.txt
Dateien sind z.B neun mal vorhanden mit anderen Werten in Block fünf und sechs.
...
Die zusammengefasste Datei soll in
12345678_0300_1_rco_123_yyy.txt ... gespeichert werden.
Da Block fünf und sechs variabel sind, müssen sie im Namen der Zieldatei entweder weggelassen werden oder ich benötige eine Bildungsregel für die beiden Blöcke.
Gruß
Friemler
Moin Hausboot,
mit Powershell liefe das auf einen Einzeiler hinaus
Im Beispiel wird in dem Ordner nur auf Dateien mit der Endung *.txt gefiltert.
Die Ausgabedateien im jeweiligen Ordner sehen dann so aus:
Grüße Uwe
mit Powershell liefe das auf einen Einzeiler hinaus
dir 'C:\ordner' -Filter *.txt | ?{$_.Name -match '^[^_]+_\d{4}'} | %{(gc $_.FullName | Out-String).Replace(".",",") | Add-Content -Path ($_.DirectoryName + "\" + $matches + ".txt")}
Die Ausgabedateien im jeweiligen Ordner sehen dann so aus:
12345678_0300.txt
12345678_0320.txt
....
Grüße Uwe
Hallo Hausboot,
OK, here we go.
Es ist allerdings eine VBScript-Lösung daraus geworden, da mir Batchscript dafür suboptimal erschien.
Das Script z.B. als "MergeFiles.vbs" speichern. Das Script kann dann folgendermaßen aufgerufen werden:
Alternativ kann auch per Drag&Drop das Icon des Verzeichnisses auf dem Icon des Scripts fallengelassen werden. Das funktioniert auch mit einer Verknüpfung auf die Scriptdatei.
Gruß
Friemler
OK, here we go.
Es ist allerdings eine VBScript-Lösung daraus geworden, da mir Batchscript dafür suboptimal erschien.
Option Explicit
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Dim objFSO, objRegEx, colMatches, dicOutStreams
Dim objFile, objInStream, objOutStream
Dim strSourcePath, strFileGroup, strOutFileName, strOutFilePath
If WScript.Arguments.Count > 0 Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set dicOutStreams = CreateObject("Scripting.Dictionary")
Set objRegEx = New RegExp
strSourcePath = WScript.Arguments(0)
objRegEx.Pattern = "^([^_]+)_([0-9]+)_([^_]+)_(ra)_([^_]+)_([^\.]+)\.(txt)$"
objRegEx.IgnoreCase = True
If objFSO.FolderExists(strSourcePath) Then
For Each objFile In objFSO.GetFolder(strSourcePath).Files
Set colMatches = objRegEx.Execute(objFile.Name)
If colMatches.Count > 0 Then
If colMatches(0).SubMatches.Count > 0 Then
strFileGroup = colMatches(0).SubMatches(1)
If Not dicOutStreams.Exists(strFileGroup) Then
strOutFileName = objRegEx.Replace(objFile.Name, "$1_$2_$3_rco.$7")
strOutFilePath = objFSO.BuildPath(strSourcePath, strOutFileName)
Set objOutStream = objFSO.CreateTextFile(strOutFilePath, True)
Call dicOutStreams.Add(strFileGroup, objOutStream)
Else
Set objOutStream = dicOutStreams(strFileGroup)
End If
Set objInStream = objFile.OpenAsTextStream(ForReading)
Call objOutStream.Write(objInStream.ReadAll)
objInStream.Close
End If
End If
Next
For Each objOutStream In dicOutStreams.Items
objOutStream.Close
Next
Else
WScript.Echo "Das angegebene Verzeichnis existiert nicht."
End If
Else
WScript.Echo "Bitte geben Sie das Verzeichnis mit den Quelldateien an."
End If
Das Script z.B. als "MergeFiles.vbs" speichern. Das Script kann dann folgendermaßen aufgerufen werden:
cscript /nologo "Pfad-zum-Script\MergeFiles.vbs" "Pfad-zum-Verzeichnis-mit-den-Dateien"
Alternativ kann auch per Drag&Drop das Icon des Verzeichnisses auf dem Icon des Scripts fallengelassen werden. Das funktioniert auch mit einer Verknüpfung auf die Scriptdatei.
Gruß
Friemler
Moin Hausboot,
anscheinend ist bei der Übernahme des Quelltextes etwas schief gegangen. Um das auf jeden Fall zu vermeiden, klicke in der rechten oberen Ecke der Codebox (blau-weiß gestreiftes Feld mit dem Quellcode) auf "
Gruß
Friemler
anscheinend ist bei der Übernahme des Quelltextes etwas schief gegangen. Um das auf jeden Fall zu vermeiden, klicke in der rechten oberen Ecke der Codebox (blau-weiß gestreiftes Feld mit dem Quellcode) auf "
Quelltext
" und kopiere den Scriptcode aus dem sich dann öffnenden Fenster in einen Texteditor Deiner Wahl. Dann "Speichern als..." mit der Dateierweiterung vbs
. Abtippen oder das Kopieren direkt aus der Codebox führt regelmäßig zu Fehlern.Gruß
Friemler
Zitat von @Hausboot:
ich habe folgenden Text (dir "C:\Users\Werner\patternt" -Filter *.txt | ?{$_.Name -match '^[^_]+_\d{4}'} |
%{(gc $_.FullName | Out-String).Replace(".",",") | Add-Content -Path ($_.DirectoryName + "\" +
$matches + ".txt")} in die vbs-Datei eingegeben.
Folgende Fehlermeldung wird beim Starten des Scipts angezeigt: Zeile 1, Zeichen 46, Fehler: Ungültiges Zeichen, Code
800A0408. Was könnte den Fehler verursachen?
Das ist kein VBS, sondern Powershell !! Du gibst es also entweder direkt in eine Powershell-Konsole(powershell.exe) ein. Wichtige Hinweise s. Anleitung unten:ich habe folgenden Text (dir "C:\Users\Werner\patternt" -Filter *.txt | ?{$_.Name -match '^[^_]+_\d{4}'} |
%{(gc $_.FullName | Out-String).Replace(".",",") | Add-Content -Path ($_.DirectoryName + "\" +
$matches + ".txt")} in die vbs-Datei eingegeben.
Folgende Fehlermeldung wird beim Starten des Scipts angezeigt: Zeile 1, Zeichen 46, Fehler: Ungültiges Zeichen, Code
800A0408. Was könnte den Fehler verursachen?
Anleitung: Wie starte ich Powershell-Scripte
- Zuerst speichert man den Code in einer Textdatei mit der Endung .ps1.
- Wenn man zum ersten mal Powershell-Scripte ausführt, musst man einmalig vorher noch das Ausführen von Scripten im User-Account freischalten. Dazu öffnet man eine Powershell-Konsole und gibt dort den Befehl
Set-ExecutionPolicy RemoteSigned -Force
ein. Um diese Policy für alle User auf dem Rechner zu setzen muss man diesen Befehl in einer Powershell-Konsole mit Admin-Rechten starten. Noch ein Hinweis für 64-Bit-Systeme: Hier sollte sowohl für die 32bit und 64Bit Variante der Powershell die Policy in einer Admin-Konsole gesetzt werden:Set-ExecutionPolicy RemoteSigned -Force; start-job { Set-ExecutionPolicy RemoteSigned -Force } -RunAs32
- Jetzt kann das Powershell-Script wie weiter unten erläutert in einer Powershell-Konsole oder aus einer CMD-Fenster heraus ausgeführt werden. Wer lieber mit der Maus arbeitet macht einen Rechtsklick auf die Script-Datei und wählt: Mit Powershell ausführen.
- Alternativ lässt sich ein Script auch ohne das globale Ändern der ExecutionPolicy ausführen indem man die Policy als Parameter auf der Kommandozeile mitgibt:
powershell.exe -ExecutionPolicy RemoteSigned -File "C:\Pfad\Script.ps1"
Starten eines Scriptes in einer Powershell-Konsole
Immer den kompletten Pfad zum Script angeben, und wenn er Leerzeichen beinhaltet in Anführungszeichen einschließen:"C:\Pfad\script.ps1"
.\script.ps1
Starten von PS-Scripten aus Batch und Kommandozeilen heraus:
Hier gibt es unterschiedliche Methoden, je nach Anforderungen gibt es hier einige Besonderheiten vor allem bei Leerzeichen in Pfaden zu beachten!Der einfachste Aufruf sieht hier so aus:
powershell.exe -File "C:\Pfad\Script.ps1"
powershell.exe -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
powershell.exe -command "&'C:\Pfad\Script.ps1' -par1 'Wert1' -par2 'Wert2'"
powershell.exe -command "&'C:\Pfad\Script1.ps1';&'C:\Pfad\Script2.ps1'"
powershell -?
in einer Konsole an.Starten von PS-Scripten in der Aufgabenplanung (Taskplaner)
In der jeweiligen Aktion unter "Programm/Script" trägt man powershell.exe ein und unter "Argumente hinzufügen (optional)" trägt man wie oben geschrieben alles was hinter powershell.exe kommt ein - also z.B. -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
Hallo Hausboot,
dann poste bitte den Inhalt Deiner Scriptdatei unter Verwendung von Codetags. Syntaxfehler heißt, Du hast den Quelltext irgendwie falsch übernommen. Ach ja, den Quellcode nicht mit Word speichern und nachher umbenennen. Das ist dann kein reines Textformat und der VBScript-Interpreter kann die Datei nicht "verstehen".
Gruß
Friemler
dann poste bitte den Inhalt Deiner Scriptdatei unter Verwendung von Codetags. Syntaxfehler heißt, Du hast den Quelltext irgendwie falsch übernommen. Ach ja, den Quellcode nicht mit Word speichern und nachher umbenennen. Das ist dann kein reines Textformat und der VBScript-Interpreter kann die Datei nicht "verstehen".
Gruß
Friemler
[OFF TOPIC]
Moin Uwe,
die obige (sehr gute) "Wie starte ich PowerShell-Scripte?"-Anleitung hast Du ja anscheinend schon irgendwo dauerhaft gespeichert.
Du könntest noch ergänzen, dass man PS-Scriptdateien auch mit
starten kann, ohne die Execution Policy vorher ändern zu müssen. Das macht es Newbies etwas leichter, einen kurzen Script-Test auszuführen.
Gruß
Friemler
[/OFF TOPIC]
Moin Uwe,
die obige (sehr gute) "Wie starte ich PowerShell-Scripte?"-Anleitung hast Du ja anscheinend schon irgendwo dauerhaft gespeichert.
Du könntest noch ergänzen, dass man PS-Scriptdateien auch mit
powershell.exe -ExecutionPolicy RemoteSigned -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
Gruß
Friemler
[/OFF TOPIC]
Hi Friemler,
yip, hatte ich noch vergessen, Danke für den Hinweis, werde ich sofort nachtragen
Grüße Uwe
yip, hatte ich noch vergessen, Danke für den Hinweis, werde ich sofort nachtragen
Grüße Uwe
Zitat von @Hausboot:
danke für den Hinweis. Jetzt funktioniert es.
Wie kann man es lösen, dass die Pfade zu den bearbeitenden Dateien nicht mehr statisch, sonder per Eingabefenster
ausgewählt werden können. Ist sowas möglich?
klar, indem du im Script Parameter verwendest und dann auf der Kommandozeile den Pfad übergibst:danke für den Hinweis. Jetzt funktioniert es.
Wie kann man es lösen, dass die Pfade zu den bearbeitenden Dateien nicht mehr statisch, sonder per Eingabefenster
ausgewählt werden können. Ist sowas möglich?
param(
[string]$path
)
dir $path -Filter *.txt | ?{$_.Name -match '^[^_]+_\d{4}'} | %{(gc $_.FullName | Out-String).Replace(".",",") | Add-Content -Path ($_.DirectoryName + "\" + $matches + ".txt")}
powershell.exe -File "C:\Pfad\Script.ps1" "C:\deinpfad"
Grafische Sachen sind selbstverständlich auch möglich, da Powershell auf .NET basiert und das ganze NET-Framework nutzen kann.
Beispiel mit einem FolderBrowserDialog zur Auswahl des Pfades:
Add-Type -AssemblyName System.Windows.Forms
$dlg = new-object System.Windows.Forms.FolderBrowserDialog
if($dlg.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){
dir $dlg.SelectedPath -Filter *.txt | ?{$_.Name -match '^[^_]+_\d{4}'} | %{(gc $_.FullName | Out-String).Replace(".",",") | Add-Content -Path ($_.DirectoryName + "\" + $matches + ".txt")}
}
Zitat von @Hausboot:
Hallo Uwe,
meine letzte Frage. Wo füge ich den von Dir geposteten Quelltext ein? Ich kann zwar einen Ordner auswählen, weiß
aber dann nicht mehr weiter.
hä ???Hallo Uwe,
meine letzte Frage. Wo füge ich den von Dir geposteten Quelltext ein? Ich kann zwar einen Ordner auswählen, weiß
aber dann nicht mehr weiter.
das sind jeweils eigenständige Scripte die komplett sind ...