Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Textdatei splitten in Anzahl Datensätze aus Originaldatei

Frage Entwicklung Batch & Shell

Mitglied: lexura

lexura (Level 1) - Jetzt verbinden

13.02.2014, aktualisiert 14.02.2014, 2300 Aufrufe, 7 Kommentare, 3 Danke

Guten Tag an die Profis,

ich stehe vor einem Problem mit einer .txt Datei. Wir erstellen eine .txt datei mit Daten aus einem SQL-Server.
Jeder Datensatz belegt dabei eine feste Satzlänge (855 Zeichen) in der .txt Datei.
Die Daten in der .txt Datei werden fortlaufend geschrieben.

Es wird jeden Tag eine neue Datei mit unterschiedlicher Anzahl an Datensätzen erstellt.

Jetzt ist meine Aufgabe dazu, aus der EINEN .txt Datei für jeden darin enthaltenen Datensatz (je 855 Zeichen) eine eigene .txt Datei zu erstellen und diese dann in einem Unterverzeichnis zur Verfügung zu stellen. Quasi die Originaldatei zu splitten in die Anzahl der enthaltenen Datensätze.

Ein Programmcode in powershell oder vbs wäre für mich die Beste Wahl.

Kann jemand helfen ???

Besten Dank im voraus, Gruß lexura

Mitglied: bastla
LÖSUNG 13.02.2014, aktualisiert 14.02.2014
Hallo lexura und willkommen im Forum!

Da Du keine näheren Angaben zu den gewünschten Datei-/Verzeichnisnamen machst, verwende ich für die Ausgabe das Tagesdatum:
01.
Ein = "D:\Gesamtdatei.txt" 
02.
Zeichenanzahl = 855 
03.
Basisordner = "D:\" 'unter diesem Ordner wird der Unterordner erstellt 
04.
 
05.
Set fso = CreateObject("Scripting.FileSystemObject") 
06.
 
07.
Datum = Right(Date, 4) & "-" & Mid(Date, 4, 2) & "-" & Left(Date, 2) 'Datum in der Form "JJJJ-MM-TT" 
08.
Pfad = fso.BuildPath(Basisordner, Datum) 'Ordnerpfad erstellen 
09.
 
10.
T = fso.OpenTextFile(Ein).ReadAll 'Datei in String einlesen 
11.
Anzahl = Int(Len(T) / Zeichenanzahl) 'Anzahl vollständiger Datensätze ermitteln 
12.
 
13.
If Not fso.FolderExists(Pfad) Then fso.CreateFolder(Pfad) 'Ordner erzeugen 
14.
 
15.
'Zählschleife für die formatierte Ausgabe der laufenden Nummer (4-stellig mit führenden Nullen) 
16.
For i = 10001 To 10000 + Anzahl 
17.
    'Datei mit dem Namen "JJJJ-MM-TT_####.txt" erzeugen 
18.
    'Dateiinhalt: Teilstring ab Position (Abschnittsnummer - 1) * Zeichenanzahl mit Länge Zeichenanzahl 
19.
    'Abschnittsnummer: i - 10000 
20.
    fso.CreateTextFile(fso.BuildPath(Pfad, Datum & "_" & Right(i, 4)) & ".txt").Write Mid(T, (i - 10001) * Zeichenanzahl + 1, Zeichenanzahl) 
21.
Next
Grüße
bastla
Bitte warten ..
Mitglied: colinardo
LÖSUNG 13.02.2014, aktualisiert 14.02.2014
Hi lexura,
und wenn du Powershell willst:
01.
$infile = "D:\data.txt"  
02.
$outpath = "D:\Ausgabeordner" 
03.
$zeichen = 855 
04.
$content = gc $infile | out-string 
05.
$length = ($content | measure -Character).Characters 
06.
$parts = 0 
07.
if($length -gt $zeichen){ 
08.
  $parts = [int]($length/$zeichen) 
09.
}else{ 
10.
  $parts = 1 
11.
  $zeichen = $length 
12.
13.
for($i=0;$i -lt $parts;$i++){ 
14.
  echo "$($content.Substring($i*$zeichen,$zeichen))" | out-file "$outpath\$(get-date -Format "yyyy-MM-dd")_$($i+1).txt" 
15.
}
Die Ausgabe der Dateien erfolgt mit dem aktuellen Datum und einem Zähler für die Abschnitte: JJJJ-MM-TT_[Zähler].txt

Grüße Uwe
Bitte warten ..
Mitglied: lexura
14.02.2014, aktualisiert um 08:15 Uhr
Vielen vielen Dank !!! Die Scripte sind perfekt. Schön wenn Profis sich so unkompliziert bereit erklären zu helfen.

mit den freundlichsten und hochachtungsvollen Grüßen
Ralf
Bitte warten ..
Mitglied: lexura
14.02.2014 um 11:35 Uhr
Hallo nochmal,
nach den ersten Tests sind jetzt doch noch ein paar Hindernisse aufgetaucht. Das Ziel muss es sein Dateien zu haben die eine feste Satzlänge von 855 Zeichen haben, keinen BOM am Beginn der Datei und kein CRLF am Ende der Datei haben und die Dateien müssen im Format UTF-8 sein.

Ich habe mir das Powershellscript von Uwe als Basis genommen. Eine Kollegin probiert sich in VBS.

Das ich kein Programmierer bin, seht ihr wahrscheinlich gleich an meinem aktuellen Script. Wir hatten vorher schon die Ausgangsdatei vom BOM mit einem Powershell-Script bereinigt. Den Code habe ich mal einfach an das Script von Uwe angefügt. Das geht bestimmt auch eleganter, aber es funktioniert erstmal face-smile

Ich habe jetzt im Ausgangsordner ( ....\noBOM) alle Dateien ohne BOM und in UTF-8 liegen, leider noch inkl. CRLF am Ende.

Kann mir einer das Script vervollständigen, damit bei jeder Datei das CRLF am Ende entfernt wird, kein BOM am Beginn der Dateien steht, sie im UTF-8 Format sind und die Satzlänge genau 855 Zeichen beträgt ???

Hier mein vorläufiges angepasstes Script:

$date = Get-Date -Format "yyyy-MM-dd"
$infile = "D:\Ausgangsdatei.txt"
$outpath = "D:\Uebermittlungsdateien\"
$zeichen = 885
$content = gc $infile | out-string
$length = ($content | measure -Character).Characters
$parts = 0
if($length -gt $zeichen){
$parts = [int]($length/$zeichen)
}else{
$parts = 1
$zeichen = $length
}
for($i=0;$i -lt $parts;$i++){
echo "$($content.Substring($i*$zeichen,$zeichen))" | out-file "$outpath\$($date)_$($i+1).txt"
}

set-location "D:\Uebermittlungsdateien\"
foreach($i in ls -name *.txt)
{
$file = get-content $i
$encoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines("D:\Uebermittlungsdateien_noBOM\" + $i, $file, $encoding)
}



Um CRLF am Ende einer Datei zu entfernen, haben wir bislang ein VBS benutzt. Dieses kann aber nur mit einer Datei klarkommen und nicht mit allen Dateien im Zielordner.

Hier mal der Ansatz in VBS: (hoffe das kann einer in Powershell nachstellen)


' File: crlf-entfernen.vbs

Option Explicit

Dim WSHShell, fso, FileIn, FileOut
Dim Datei, Text, Txt, i, arrSort, arrTest(), oArgs

Set WSHShell = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
set oArgs = Wscript.Arguments

' Zuweisen von Admin-Rechten
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If WScript.Arguments.length =0 Then
Set objShell = CreateObject("Shell.Application")
'Pass a bogus argument with leading blank space, say [ uac]
objShell.ShellExecute "wscript.exe", Chr(34) & _
WScript.ScriptFullName & Chr(34) & " uac", "", "runas", 1
Else
'Add your code here
End If


' Fals ein Argument übergeben wurde, sollte es einen Dateinamen
' enthalten
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For i = 0 to oArgs.Count - 1 ' hole alle Argumente
Datei = oArgs.item(i)
If not fso.FileExists( Datei ) then
MsgBox UCase( Datei ) & " existiert nicht!" & vbCRLF & vbCRLF & " . . . das ist das Ende.", , WScript.ScriptName
WScript.Quit
End If
Exit For ' nur das erste Argument reicht
Next


' Gibt's keinen Dateinamen, wird halt das Skript gelesen
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if Datei = "" then Datei = WScript.ScriptName


' Datei komplett einlesen
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set FileIn = FSO.OpenTextFile(Datei, 1 ) ' Datei zum Lesen öffnen

Text = FileIn.ReadAll

FileIn.Close
Set FileIn = nothing



' Inhalt bearbeiten
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Text = Replace( Text, vbCRLF , "" )
Text = Replace( Text, vbCRLF , "" )



' (Ziel-) Datei schreiben
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Datei = fso.GetBaseName( Datei ) & "-.txt"

Set FileOut = FSO.OpenTextFile( Datei , 2, true) ' Datei zum Screiben öffnen; 2: immer neu anlegen

FileOut.Write( Text )

FileOut.Close
Set FileOuT = nothing


Hoffe es euch genug erklärt zu haben. Evtl. hat ja jemand noch nen Lösungsansatz für mich.

Gruß Ralf
Bitte warten ..
Mitglied: colinardo
LÖSUNG 14.02.2014, aktualisiert um 12:13 Uhr
01.
$infile = "D:\Ausgangsdatei.txt" 
02.
$outpath = "D:\Uebermittlungsdateien" 
03.
$zeichen = 855 
04.
$content = gc $infile | out-string 
05.
$length = ($content | measure -Character).Characters 
06.
$parts = 0 
07.
if($length -gt $zeichen){ 
08.
  $parts = [int]($length/$zeichen) 
09.
}else{ 
10.
  $parts = 1 
11.
  $zeichen = $length 
12.
13.
for($i=0;$i -lt $parts;$i++){ 
14.
  $file = $content.Substring($i*$zeichen,$zeichen).TrimEnd("`r`n") 
15.
  [System.IO.File]::WriteAllText("$outpath\$(get-date -Format "yyyy-MM-dd")_$($i+1).txt",$file) 
16.
}
Ansonsten poste doch mal einen Ausschnitt der Quelldatei (aber bitte mit CodeTags), oder schick so eine Datei mal via PM, damit wir hier nicht raten müssen...Danke.
Sind die Zeilenumbrüche zufällig die Trennung der Abschnitte?, dann könnte man das auch einfacher lösen ...
Grüße Uwe
Bitte warten ..
Mitglied: lexura
14.02.2014 um 12:11 Uhr
Yes, bislang sieht es SUPER aus. KNIEFALL !!!
Sollte bei weiteren Tests noch etwas auffallen, melde ich mich nochmals hier.

DANKE DANKE DANKE !!!
Bitte warten ..
Mitglied: lexura
17.02.2014 um 11:41 Uhr
Nochmals ein großen Dank an bastla und Uwe. Wir haben uns jetzt für die Powershell-Variante entschieden.
Seit heute läuft das fertige Script in unserer Produktionsumgebung einwandfrei.

Hier nochmals das finale Script:

$infile = "D:\Anwendungen\Eingang\Export.txt"
$outpath = "D:\Anwendungen\Ausgang\"
$zeichen = 885
$content = gc $infile | out-string
$length = ($content | measure -Character).Characters
$parts = 0
if($length -gt $zeichen){
$parts = [int]($length/$zeichen)
}else{
$parts = 1
$zeichen = $length
}
for($i=0;$i -lt $parts;$i++){
$file = $content.Substring($i*$zeichen,$zeichen).TrimEnd("`r`n")
[System.IO.File]::WriteAllText("$outpath\UTF-8_$(get-date -Format "yyyy-MM-dd")_$($i+1).txt",$file)
}
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst Powershell - In Textdatei suchen und ersetzen (5)

Frage von Raaja89 zum Thema Batch & Shell ...

C und C++
gelöst Anzahl der Buchstaben in einem String Element Array C++ (3)

Frage von Protected zum Thema C und C ...

Zusammenarbeit
Minimale Anzahl Admins? (6)

Frage von 1410640014 zum Thema Zusammenarbeit ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (21)

Frage von Xaero1982 zum Thema Microsoft ...

Windows Update
Treiberinstallation durch Windows Update läßt sich nicht verhindern (17)

Frage von liquidbase zum Thema Windows Update ...

Windows Tools
gelöst Aussendienst Datensynchronisierung (12)

Frage von lighningcrow zum Thema Windows Tools ...

Windows Server
Suche passender Treiber (12)

Frage von stolli zum Thema Windows Server ...