Bestimmten Bereich einer Textdatei ausgeben mittels Batch
Hallo,
gibt es eine Möglichkeit eine Textdatei mittels Batch zu durchsuchen und einen bestimmten Teil davon dann aber nur auszugeben?
Folgendes Beispiel:
Meine Textdatei sieht wie folgt aus:
Besteht hier nun die Möglichkeit nach Episode zu suchen und dann alles was nach Episode folgt bis Beschreibung auszugeben und bei Beschreibung zu stoppen?
Das was zwischen Episode steht also 1,2,3 usw. variert, ist also nicht immer eine bestimmte Anzahl.
Ich kenne mich etwas mit Batchrex aus und wie ich eine normale Textdatei durchsuche und dann eben das auszugeben was dort drin steht, allerdings weis ich nicht ob es möglich ist nur einen bestimmten Bereich zu durchsuchen.
Ich denke hier muss man mit Regular Expressions arbeiten, damit kenne ich mich aber leider nicht wirklich aus.
Hoffe konnte vermittlen was ich gerne hätte.
Gruß Django
gibt es eine Möglichkeit eine Textdatei mittels Batch zu durchsuchen und einen bestimmten Teil davon dann aber nur auszugeben?
Folgendes Beispiel:
Meine Textdatei sieht wie folgt aus:
Episode
1
2
3
4
5
6
Beschreibung
Hier steht eine Beschreibung
usw.
Besteht hier nun die Möglichkeit nach Episode zu suchen und dann alles was nach Episode folgt bis Beschreibung auszugeben und bei Beschreibung zu stoppen?
Das was zwischen Episode steht also 1,2,3 usw. variert, ist also nicht immer eine bestimmte Anzahl.
Ich kenne mich etwas mit Batchrex aus und wie ich eine normale Textdatei durchsuche und dann eben das auszugeben was dort drin steht, allerdings weis ich nicht ob es möglich ist nur einen bestimmten Bereich zu durchsuchen.
Ich denke hier muss man mit Regular Expressions arbeiten, damit kenne ich mich aber leider nicht wirklich aus.
Hoffe konnte vermittlen was ich gerne hätte.
Gruß Django
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 347848
Url: https://administrator.de/contentid/347848
Ausgedruckt am: 23.11.2024 um 17:11 Uhr
10 Kommentare
Neuester Kommentar
Der Regex Support von Batch beschränkt sich auf das bisschen, was FINDSTR versteht (wenn man nicht auf andere Sprachen oder Drittprogramme zurückgreifen will).
Gehen wir von folgenden Voraussetzungen aus:
- Die Textdatei ist in einer Single Byte Codepage codiert.
- Die Suchbegriffe bilden eine separate Zeile (ohne voran- oder nachgestellte Leer- oder sonstige Zeichen).
- Die maximale Länge einer Zeile überschreitet nicht 1021 Zeichen.
Grüße
rubberman
Gehen wir von folgenden Voraussetzungen aus:
- Die Textdatei ist in einer Single Byte Codepage codiert.
- Die Suchbegriffe bilden eine separate Zeile (ohne voran- oder nachgestellte Leer- oder sonstige Zeichen).
- Die maximale Länge einer Zeile überschreitet nicht 1021 Zeichen.
@echo off &setlocal
set "infile=test.txt"
for /f "delims=:" %%i in ('findstr /nx "Episode" "%infile%"') do set "begin=%%i"
for /f "delims=:" %%i in ('findstr /nx "Beschreibung" "%infile%"') do set /a "end= %%i - begin - 1"
setlocal EnableDelayedExpansion
<"!infile!" (
for /l %%i in (1 1 %begin%) do set /p "="
for /l %%i in (1 1 %end%) do (
set "line=" &set /p "line="
echo(!line!
)
)
pause
Grüße
rubberman
Ja, /nx ist hier kurz für /n /x. Das /n führt dazu, dass FINDSTR der gefundenen Zeile die Zeilennummer und ein Doppelpunkt voranstellt (und die Zeilennummer ist das, was wir jeweils brauchen). Das /x bedeutet, dass die gesamte Zeile dem Suchpattern entsprechen muss. Anderenfalls würden auch Zeilen gefunden, die das Suchpattern nur an irgendeiner Stelle beinhalten.
Das
Die erste FOR /L Schleife liest also alle Zeilen bis zum Beginn des gesuchten Blocks. Der Zeileninhalt wird aber keiner Variablen zugewiesen (also wird er de facto verworfen).
Die zweite FOR /L Schleife liest die vorher mit SET /A berechnete Anzahl an Zeilen jeweils in Variable
Grüße
rubberman
Das
<"!infile!" (
leitet den Filestream an den kompletten Klammernblock um, sodass mit SET /P jeweils eine Zeile gelesen wird.Die erste FOR /L Schleife liest also alle Zeilen bis zum Beginn des gesuchten Blocks. Der Zeileninhalt wird aber keiner Variablen zugewiesen (also wird er de facto verworfen).
Die zweite FOR /L Schleife liest die vorher mit SET /A berechnete Anzahl an Zeilen jeweils in Variable
line
ein und gibt sie mit ECHO aus.Grüße
rubberman
Unter den gleichen Prämissen wie bei rubberman ist diese Batchdatei etwas simpler:
Mit PowerShell tut's ein (wenn auch komplexer) Einzeiler, nutzbar von der cmdline oder auch in einer Batchdatei:
Dasselbe als PowerShell Script ohne Aliase:
Kern ist ein Regulärer Ausdruck (RegEX) mit Lookarounds
Gruß LotPings
@echo off &setlocal
set "InFile=test.txt"
set "Von=Episode"
set "Bis=Beschreibung"
set "Flag="
For /f "tokens=1* delims=]" %%A in ('find /V /N "§+#*$" ^<%InFile%') DO (
if "%%B"=="%Bis%" Set "Flag="
If defined Flag echo:%%B
if "%%B"=="%Von%" Set "Flag=1"
)
Mit PowerShell tut's ein (wenn auch komplexer) Einzeiler, nutzbar von der cmdline oder auch in einer Batchdatei:
powershell -NoP -C "gc test.txt -raw |sls '(?sm)(?<=^Episode\r?\n).*(?=\r?\nBeschreibung)'|%{$_.Matches.value}"
Dasselbe als PowerShell Script ohne Aliase:
Get-Content test.txt -Raw |
Select-String '(?sm)(?<=^Episode\r?\n).*(?=\r?\nBeschreibung)'|
ForEach-Object {
$_.Matches.value
}
Kern ist ein Regulärer Ausdruck (RegEX) mit Lookarounds
Gruß LotPings
Zitat von @Django.Durano:
Ich kannte bisher nur das ich den Filestream in eine Textdatei umleiten kann mit > bzw. >>
Ist das hier quasi so eine Art Umkehrung, das die Textdatei eingelesen und hierdurch dann übergeben wird an das nachfolgende?
Fast. Ich kannte bisher nur das ich den Filestream in eine Textdatei umleiten kann mit > bzw. >>
Ist das hier quasi so eine Art Umkehrung, das die Textdatei eingelesen und hierdurch dann übergeben wird an das nachfolgende?
>
und >>
leiten das stdout an einen Filestream um, während <
einen Filestream an das stdin umleitet. Insgesamt gibt es 3 Standarddatenströme. Der 3. ist das stderr. Hast vielleich schon gemerkt, dass du 2>
oder 2>>
schreiben musst, um Fehlermeldungen umzuleiten.Grüße
rubberman
@rubberman
@django
- Der String "§+#*$" in Verbindung mit /V als unwahrscheinlich vorkommender Teil (soll alles durchlassen, es geht um die Numerierung)
> find /V /N "$$$" <test.txt
[1]Episode
[2]1
[3]2
[4]3
[5]4
[6]5
[7]6
[8]
[9]Beschreibung
[10]Hier steht eine Beschreibung
[11]
[12]usw.
- Ich finde eine Schleife einfacher als vier - aber ein paar Erklärungen mehr hätten nicht geschadet.
- find statt findstr wegen der eckigen Klammer als Abgrenzung ( die schließende Klammer dürfte seltener als erstes Zeichen einer Zeile auftreten als ein Doppelpunkt)
- Die Umleitung damit find nicht den Dateinamen mit ausgibt.
- Das Flag statt eines Variableninhalts der EnableDelayedExpansion erfordern würde (if defined funktioniert auch ohne)
- Flag funktioniert als Schalter wann ausgegeben werde soll
- mit tokens wird festgelegt wieviele Variablen genutzt werden 1=%%A, *=%%B (Rest der Zeile) %%A enthält nur die verworfene Numerierung in eckigen Klammern [1] etc.
Zitat von @77559:
@rubberman
Joa und der leere String "" in Verbindung mit /V findet alle Zeilen die nicht nichts enthalten und auch nicht keinen Zeilenumbruch haben, also alle Zeilen incl. Leerzeilen @rubberman
- Der String "§+#*$" in Verbindung mit /V als unwahrscheinlich vorkommender Teil (soll alles durchlassen, es geht um die Numerierung)
Ansonsten war mir klar, wie es funktioniert. (Die Erklärung wird aber für Django.Durano sicher nützlich sein.)
Grüße
rubberman