Batch oder Powershell: Teile einer Textdatei kopieren (mehrere Zeilen)
Hallo,
ich habe mehrere txt-Dateien, in denen jeweils mehrere Abschnitte mit Daten vorliegen. Nun möchte ich jede dieser Textdateien "aufteilen", d.h. Abschnitte einer Art sollen in eine Datei kopiert werden, Abschnitte einer anderen Art in eine andere Datei. Konkret sieht das so aus:
Dateianfang
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_2
mehrere Zeilen
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_2
mehrere Zeilen
usw.
Dateiende
Abschnitt_Art_1 beginnt immer mit einer Zeile mit den ersten beiden Zeichen "#A" gefolgt von einem Leerzeichen
Abschnitt_Art_2 beginnt immer mit einer Zeile mit den ersten beiden Zeichen "#B" gefolgt von einem Leerzeichen
Innerhalb der Abschnitte gibt es keine Zeilen, die mit dieser Zeichenfolge beginnen.
Innerhalb der Abschnitte ist die Zahl der Zeilen variabel.
Es gibt bis zu 20.000 Abschnitte in einer Datei, die Reihenfolge der Abschnitte ist nicht festgelegt.
Nun soll jede Zeile geprüft werden, ob sie ein Abschnittsbeginn ist und wenn ja von welcher Art. Dann sollen diese erste Zeile und alle Folgezeilen bis zum nächsten Abschnittsbeginn in die passende Zieldateien kopiert werden, alle Abschnitte der Art_1 in die gemeinsame Zieldatei 1, alle der Art_2 in die gemeinsame Zieldatei 2.
Ich dachte, ich käme hiermit weiter, aber wenn ich die batch ausführe passiert nichts.
Was mache ich falsch?
Gruß, Olaf
ich habe mehrere txt-Dateien, in denen jeweils mehrere Abschnitte mit Daten vorliegen. Nun möchte ich jede dieser Textdateien "aufteilen", d.h. Abschnitte einer Art sollen in eine Datei kopiert werden, Abschnitte einer anderen Art in eine andere Datei. Konkret sieht das so aus:
Dateianfang
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_2
mehrere Zeilen
Abschnitt_Art_1
mehrere Zeilen
Abschnitt_Art_2
mehrere Zeilen
usw.
Dateiende
Abschnitt_Art_1 beginnt immer mit einer Zeile mit den ersten beiden Zeichen "#A" gefolgt von einem Leerzeichen
Abschnitt_Art_2 beginnt immer mit einer Zeile mit den ersten beiden Zeichen "#B" gefolgt von einem Leerzeichen
Innerhalb der Abschnitte gibt es keine Zeilen, die mit dieser Zeichenfolge beginnen.
Innerhalb der Abschnitte ist die Zahl der Zeilen variabel.
Es gibt bis zu 20.000 Abschnitte in einer Datei, die Reihenfolge der Abschnitte ist nicht festgelegt.
Nun soll jede Zeile geprüft werden, ob sie ein Abschnittsbeginn ist und wenn ja von welcher Art. Dann sollen diese erste Zeile und alle Folgezeilen bis zum nächsten Abschnittsbeginn in die passende Zieldateien kopiert werden, alle Abschnitte der Art_1 in die gemeinsame Zieldatei 1, alle der Art_2 in die gemeinsame Zieldatei 2.
Ich dachte, ich käme hiermit weiter, aber wenn ich die batch ausführe passiert nichts.
for %%f in (./*.txt) do (
for /f tokens=1 %%i in (%%f) do (
if %%i="#A" set ziel=A.txt
if %%i="#B" set ziel=B.txt
echo %%i>>ziel
)
)
Was mache ich falsch?
Gruß, Olaf
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 276861
Url: https://administrator.de/contentid/276861
Ausgedruckt am: 25.11.2024 um 03:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo,
Ist noch nicht perfekt, aber vielleicht hilft dir diese PS Script
Viele Grüße
Ist noch nicht perfekt, aber vielleicht hilft dir diese PS Script
$files = Get-ChildItem *.txt
$dest = "unknown.txt"
foreach ($file in $files) {
$text = Get-Content $file
foreach ($line in $text) {
if ($line.StartsWith("#")) {
$dest = $line[1]+".txt"
}
else {
$line | out-File -append $dest
}
}
}
Viele Grüße
Powershell gefällig
Gruß jodel32
gci '.\*.txt' | %{
$dir = $_.DirectoryName
[regex]::Matches((gc $_.Fullname | out-string),'(?sim)^#(A|B) [^\n\r]*(.*?)(?=^#|\Z)').Captures | group {$_.Groups[1]} | %{$_.Group.Value | out-file "$dir\$($_.Group.Groups[1].Value).txt" -Append}
}
Hallo, Olaf,
also bei mir hat das so funktioniert:
Achte besonders auf die Anführungszeichen in Zeile 3: "%%g".
Gruß, Michael
Oh, ich hab ganz übersehen, dass du ja noch eine weitere Bedingung hattest: Innerhalb der Abschnitte beginnt keine der Zeilen mit #A oder #B.
Da muss ich wohl noch etwas nacharbeiten.
also bei mir hat das so funktioniert:
for %%f in (./*.txt) do (
for /f "tokens=*" %%g in (%%f) do (
for /f "tokens=1" %%i in ("%%g") do (
if %%i == #A echo %%g >> A.txt
if %%i == #B echo %%g >> B.txt
)
)
)
Achte besonders auf die Anführungszeichen in Zeile 3: "%%g".
Gruß, Michael
Oh, ich hab ganz übersehen, dass du ja noch eine weitere Bedingung hattest: Innerhalb der Abschnitte beginnt keine der Zeilen mit #A oder #B.
Da muss ich wohl noch etwas nacharbeiten.
Hallo, Olaf,
jetzt nochmal meine aktualisierte Fassung.
Ich hoffe, ich habe jetzt alles richtig verstanden.
Du hast eine (oder mehrere) .txt-Dateien mit etwa folgendem Inhalt:
Meine Batch-Datei sieht folgendermaßen aus:
Das Ergebnis sind zwei Dateien, einmal
A.txt:
und dann
B.txt
Das müsste es doch sein, oder?
Das Problem sind die Umgebungsvariablen innerhalb von IF-Strukturen. Achte daher auf die Ausrufezeichen in Zeile 8.
Siehe hierzu auch hier.
Gruß, Michael
jetzt nochmal meine aktualisierte Fassung.
Ich hoffe, ich habe jetzt alles richtig verstanden.
Du hast eine (oder mehrere) .txt-Dateien mit etwa folgendem Inhalt:
#A zeile 1
#B Zeile 2
Zeile 3
Zeile 4
#A Zeile 5
#B Zeile 6
#A Zeile 7
Zeile 8
Meine Batch-Datei sieht folgendermaßen aus:
@echo off
setlocal enabledelayedexpansion
for %%f in (.\*.txt) do (
for /f "tokens=*" %%g in (%%f) do (
for /f "tokens=1" %%i in ("%%g") do (
if %%i == #A set ziel=A.txt
if %%i == #B set ziel=B.txt
echo %%g >> !ziel!
)
)
)
Das Ergebnis sind zwei Dateien, einmal
A.txt:
#A zeile 1
#A Zeile 5
#A Zeile 7
Zeile 8
und dann
B.txt
#B Zeile 2
Zeile 3
Zeile 4
#B Zeile 6
Das müsste es doch sein, oder?
Das Problem sind die Umgebungsvariablen innerhalb von IF-Strukturen. Achte daher auf die Ausrufezeichen in Zeile 8.
Siehe hierzu auch hier.
Gruß, Michael
Hallo Olaf.
Ich weiß nicht wie es in Powershell ist, aber was den Befehlszeileninterpreter CMD angeht, fallen mir ein paar Punkte ein:
1. If-Vergleiche von Zeichenketten werden mit doppelten Gleichheitszeichen (==) gemacht.
2. Anführungszeichen zählen zum String dazu, d.h. sie müssen entweder auf beiden Seiten vorhanden sein oder auf beiden Seiten fehlen, sonst gibt es keine Gleichheit. ("A"=="A" und nicht A=="A")
3. Wenn du innerhalb einer For-Schleife eine Variable aufrufst, die du in derselben For-Schleife (ein paar Zeilen zuvor) geändert hast (in deinem Beispiel %ziel%), benötigst du die Direktive und die Variable muss dann statt %% in !! eingeschlossen werden (s. Beispiele meiner Vorredner).
4. tokens=1 muss in Anführungszeichen eingeschlossen werden. (siehe for /?)
Gruß
format-c
Ich weiß nicht wie es in Powershell ist, aber was den Befehlszeileninterpreter CMD angeht, fallen mir ein paar Punkte ein:
1. If-Vergleiche von Zeichenketten werden mit doppelten Gleichheitszeichen (==) gemacht.
2. Anführungszeichen zählen zum String dazu, d.h. sie müssen entweder auf beiden Seiten vorhanden sein oder auf beiden Seiten fehlen, sonst gibt es keine Gleichheit. ("A"=="A" und nicht A=="A")
3. Wenn du innerhalb einer For-Schleife eine Variable aufrufst, die du in derselben For-Schleife (ein paar Zeilen zuvor) geändert hast (in deinem Beispiel %ziel%), benötigst du die Direktive
SETLOCAL EnableDelayedExpansion
4. tokens=1 muss in Anführungszeichen eingeschlossen werden. (siehe for /?)
Gruß
format-c