dedalus2011
Goto Top

FINDSTR Befehl für strikt aufeinanderfolgende Sequenzelementen

Hallo,

gibt's eine Möglichkeit mit dem "findstr" Befehl die Sequenz ("Benutzername: ABC " (ohne die 1 am Ende, und auch wenn möglicherweise Leerzeichen dazwischen liegen) in der folgenden Struktur eindeutig zu erkennen?

Benutzername : ABC1


Die Sequenz soll aber in der Struktur

Benutzername : FGH ABC1


nicht gefunden werden. Also die Sequenzelementen müssen strikt nacheinander gefunden werden


Freue mich über jeden Hinweis

Grüße

dedalus2011

Content-Key: 183125

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

Printed on: April 19, 2024 at 23:04 o'clock

Member: bastla
bastla Apr 04, 2012 at 17:42:55 (UTC)
Goto Top
Hallo dedalus2011!

Verwende den Schalter "/c:" ...

... und gelegentlich "findstr /?"

Grüße
bastla
Member: dedalus2011
dedalus2011 Apr 04, 2012 at 17:52:02 (UTC)
Goto Top
Hallo bastla,

habe schon probiert, die Sequenz "Benutzername: ABC" wird aber nicht gefunden (wegen dem "1" am Ende). Sobald der Schalter /r verwendet wird, findet aber findstr die Sequenz "Benutzername: ABC" auch in der Struktur

Benutzername : FGH ABC1

was nicht erwünscht wird.

Grüße
dedalus2011
Member: bastla
bastla Apr 04, 2012 at 17:58:18 (UTC)
Goto Top
Hallo dedalus2011!

Soferne Du nicht ein zusätzliches "/x" oder "/e" verwendest, sollte das funktionieren:
D:>echo Benutzername : ABC1 |findstr /c:"Benutzername : ABC"
Benutzername : ABC1

D:\>echo Benutzername : FGH ABC1 |findstr /c:"Benutzername : ABC"

D:\>
bzw
D:\>type Text.txt
gibt's eine M÷glichkeit mit dem "findstr" Befehl die Sequenz ("Benutzername: ABC
 " (ohne die 1 am Ende, und auch wenn m÷glicherweise Leerzeichen dazwischen lieg
en) in der folgenden Struktur eindeutig zu erkennen?

Benutzername : ABC1


Die Sequenz soll aber in der Struktur

Benutzername : FGH ABC1

D:\>findstr /c:"Benutzername : ABC" Text.txt
Benutzername : ABC1

D:\>
Grüße
bastla
Member: dedalus2011
dedalus2011 Apr 04, 2012 at 18:14:48 (UTC)
Goto Top
Hallo bastla,

es kommen noch Leerzeichen zwischen drin (also zwischen "Benutzername" ":" und "ABC1"), und deswegen wird die Sequenz nicht gefunden. Problematisch dabei ist dass die Anzahl dieser Leerzeichen unterschiedlich sein kann. Gibt's dafür eine Lösung?

Grüße
dedalus2011
Member: bastla
bastla Apr 04, 2012 at 18:18:25 (UTC)
Goto Top
Hallo dedalus2011!

Na dann eben
findstr /r /c:"Benutzername : *ABC"
Grüße
bastla
Member: Weiricth
Weiricth Apr 04, 2012 at 19:04:59 (UTC)
Goto Top
lad dir doch Visual Studio Express runter und machs in VB.Net und gut ist
Member: dedalus2011
dedalus2011 Apr 04, 2012 at 19:15:57 (UTC)
Goto Top
Hallo bastla,

super, bei mir hat's mit

findstr /i /r /c: Benutzername *: *ABC

geklappt - die option "case-insensitive" soll bei mir auch sein ;)

Grüße
dedalus2011
Member: Biber
Biber Apr 04, 2012 at 19:19:06 (UTC)
Goto Top
Zitat von @Weiricth:
lad dir doch Visual Studio Express runter und machs in VB.Net und gut ist
Alternativ dazu vielleicht ne gebrauchte Cray?
Oder einen 476-Teile-Chrom-Vanadium-Knarrenkasten aus dem örtlichen Profi-Baumarkt?

Du hast schon "die Anforderung" gelesen und das zwischen den Zeilen stehende "Ich möchte vor der nächsten Steuerrreform fertig werden!" ?

Immer wieder erstaunt ob der Vielfältigkeit der Lösungsansätze dieses Forums
Biber
Member: Weiricth
Weiricth Apr 04, 2012 at 19:33:47 (UTC)
Goto Top
Zitat von @Biber:
> Zitat von @Weiricth:
> ----
> lad dir doch Visual Studio Express runter und machs in VB.Net und gut ist
Alternativ dazu vielleicht ne gebrauchte Cray?
Oder einen 476-Teile-Chrom-Vanadium-Knarrenkassen vom örtlichen Profi-Baumarkt?

Du hast schon "die Anforderung" gelesen und das zwischen den Zeilen stehende "Ich möchte vor der nächsten
Steuerrreform fertig werden!" ?

Immer wieder erstaunt ob der Vielfältigkeit der Lösungsansätze dieses Forums
Biber

ja stell dir vor lesen kann ich. Ich finds eher erstaunlich das es dann leute gibt die dann dumme posts machen. aber zurück zu kommen

das ist ein zweizeiler in vb.net. desweitern ist die Performance um ein wesentliches erhöht, und kein dummer anwender kann im script rumwurschteln. Und wenn jemand sowas in batch macht hat er schon so viel verstand das er es auch in vb.net hin bekommt.
Member: bastla
bastla Apr 04, 2012 at 19:43:00 (UTC)
Goto Top
@Weiricth
das ist ein zweizeiler in vb.net
Wäre doch nett von Dir, wenn Du dedalus2011 diese beiden Zeilen auch anbieten würdest ... face-wink

Grüße
bastla
Member: Weiricth
Weiricth Apr 04, 2012 at 20:04:06 (UTC)
Goto Top
ok wenns mann verkaufs fertig programmiert sinds mehr zeilen. aber hier das komplette modul.

Imports System.IO

Module Module1

    Dim p_text As String()
    Dim p_DateinameInklPfad As String


    Sub Main()
        Dim zeile As Integer = 0
        Dim suchtext As String = ""  
        p_DateinameInklPfad = "C:\test.txt"  
        lesen()

        For i As Integer = 0 To p_text.Length - 1 Step 1
            If p_text(i).IndexOf(suchtext) > 0 Then
                zeile = i
                'etweder mit exit oder ausgabe aller  
                Console.WriteLine(p_text(i))
                Exit For
            End If
        Next
    End Sub

    Public Sub lesen(Optional ByVal ToLower As Boolean = False, Optional ByVal ToUpper As Boolean = False)
        ReDim Preserve p_text(0)
        p_text(0) = "false"  
        Try
            ' --- Datei öffnen  
            Dim fs As FileStream = New FileStream(p_DateinameInklPfad, FileMode.OpenOrCreate, FileAccess.ReadWrite)
            ' --- Stream öffnen  
            Dim r As StreamReader = New StreamReader(fs)
            ' --- Zeiger auf den Anfang  
            r.BaseStream.Seek(0, SeekOrigin.Begin)
            ' --- Alle Zeilen lesen und an Console ausgeben  
            Dim i As Integer = 0
            While r.Peek() > -1
                ReDim Preserve p_text(i)
                p_text(i) = r.ReadLine()
                If ToLower Then
                    p_text(i).ToLower()
                End If
                If ToUpper Then
                    p_text(i).ToUpper()
                End If
                i = i + 1
            End While
            ' --- Reader und Stream schließen  
            r.Close()
            fs.Close()
        Catch ex As Exception
            ' txtDatei_Logfile_Schreiben(ex.Message, txt_Logfile)  
        End Try
    End Sub

End Module
Member: bastla
bastla Apr 04, 2012 at 20:12:47 (UTC)
Goto Top
Hallo Weiricth!

Falls Du doch noch ein paar Zeilen einsparen möchtest:
  • Die Variable "zeile" wird nicht wirklich verwendet.
  • Anstelle des zeilenweisen Einlesens und der Verwendung von "ReDim" böte sich ein Einlesen "am Stück" und ein "Split" anhand der Zeilenschaltungen an.

Was mir etwas fehlt, ist die Berücksichtigung der variablen Anzahl an Leerzeichen im Suchtext - Stichwort "RegEx"...

Grüße
bastla
Member: mrtux
mrtux Apr 04, 2012 at 20:16:54 (UTC)
Goto Top
Hi !

Zitat von @Weiricth:
ja stell dir vor lesen kann ich. Ich finds eher erstaunlich das es dann leute gibt die dann dumme posts machen. aber zurück
zu kommen

Ui da hat aber einer Humor mit dem Schöpflöffel inhaliert.... :-P

Mhhh c++ wäre ja auch noch eine Möglichkeit, wobei ich eher für Delphi.net wäre aber ob das mit echten zwei Zeilen klappt....Nee, die bräuchte schon für die Deklaration....Egal...

mrtux
Member: Weiricth
Weiricth Apr 04, 2012 at 20:29:43 (UTC)
Goto Top
die var zeile ist weil mir nicht klar ist ob er noch weiter machen möchte deshalb speicher ich diese raus .

des redim kommt bei mir aus ner funktion bzw klasse raus. Das grund lesen kommt von google da hab ich jetzt nicht nachgeschaut bzw. verbessert.

Bezüglich RegEx hab ich grad nicht dran gedacht hier geändert

    Sub Main()
        Dim zeile As Integer = 0
        Dim suchtext As String = "Benutzername"  
        Dim suchtext As String = "ABC"  
        p_DateinameInklPfad = "C:\test.txt"  
        lesen()

        For i As Integer = 0 To p_text.Length - 1 Step 1
            If p_text(i).IndexOf(suchtext) > 0 and  p_text(i).IndexOf(suchtext2) > 0 Then
                zeile = i
                'etweder mit exit oder ausgabe aller  
                Console.WriteLine(p_text(i))
                Exit For
            End If
        Next
    End Sub
Member: bastla
bastla Apr 04, 2012 at 20:37:44 (UTC)
Goto Top
Hallo Weiricth!
If p_text(i).IndexOf(suchtext) > 0 and p_text(i).IndexOf(suchtext2) > 0 Then
würde genau wieder zum Anfang des Problems von dedalus2011 zurückführen, da damit auch "Benutzername : FGH ABC1" gefunden würde - daher ist tatsächlich RegEx gefragt ...

Grüße
bastla
Member: Weiricth
Weiricth Apr 04, 2012 at 20:49:34 (UTC)
Goto Top
es ist zu spät zum denken

    Sub Main()
        Dim zeile As Integer = 0
        Dim myRegex As New Regex("")  
        Dim suchtext As String = ""  
        p_DateinameInklPfad = "C:\test.txt"  
        lesen()

        For i As Integer = 0 To p_text.Length - 1 Step 1
            If myRegex.IsMatch(p_text(i)) Then
                zeile = i
                'etweder mit exit oder ausgabe aller  
                Console.WriteLine(p_text(i))
                Exit For
            End If
        Next
    End Sub

den RegEx must jemand ander machen da bin ich nicht fit drin.
Member: Skyemugen
Skyemugen Apr 05, 2012 at 05:28:42 (UTC)
Goto Top
... und dat is' jetzt schneller geschrieben als findstr /i /r /c: Benutzername *: *ABC, habe ich das richtig verstanden, ja?

Glückwunsch, jetzt weiß ich, warum einige Programmierer Fantasiekosten aufrufen, wenn die alle so arbeiten *gröhl*

zwei Zeilen ... das komplette Modul >50 Zeilen, ah hätte der TE auch schneller hinbekommen als die Batchdatei zu schreiben *Kopf nick* ... + Downloadzeit + Installationszeit ... jepp, hätte sich gelohnt, kaum mehr Aufwand

was für Leute hier rumeiern, unfassbar ... und am Ende kann er das Problem nicht einmal vollends lösen ...
Mitglied: 106009
106009 Apr 05, 2012 at 05:37:49 (UTC)
Goto Top
Zitat von @Weiricth:
ja stell dir vor lesen kann ich. Ich finds eher erstaunlich das es dann leute gibt die dann dumme posts machen.

Fragt sich, wer hier "dumme posts" macht.

Typischer Fall von BTW5.
Member: Weiricth
Weiricth Apr 05, 2012 at 06:13:33 (UTC)
Goto Top
1. Leute der will doch garantiert mehr als nur Findstr in seiner dummen batch datei machen und da wird er schnell aufs ende stoßen, bzw. die arbeit die er ins eine script gesteckt hat kann er nicht so einfach ins nächste übernehmen.

2. wissen wir nicht auf wievielen rechnern er es einsetzen will, welches unterschiedlichen OS Stände die haben etc.

3. Sieht sich des mit Benutzername und Sequenz sehr nach versuch der Authentifiziertung aus, und dann kann jeder drin rumpfuschen.

@Skyemugen: ja 50 zeichen weil das Modul schon fertige funktionen hat zu wieder verwendung was mann im Internet gleich finden kann. Das eigentliche Program hat gerade mal 15 zeilen und dabei sind die zeilen die VS auto erstellt schon dabei. Zum Thema Kosten, bzw download etc. wenn man sieht das ich nicht mal 10 min für das Programm gebraucht habe (siehe post zeit) aber dedalus über 3 Std für dann eine entgültige lösung gebraucht hat frag ich mich wer hat sich hier was gespart.
Member: Skyemugen
Skyemugen Apr 05, 2012 at 06:35:50 (UTC)
Goto Top
zu 1.) Bullshit, wenn man keine Ahnung hat ... der kommt so oder so wenn dann hier her, da nutzen ihm VB.Net Schnipsel noch weniger

zu 2.) Wayne, die Batch rennt auf mehr Windows-Systemen (Windows 95? SBS 2011? ... was immer belieben) als eine aus VB.Net erstellte .exe, die dann erst einmal .NET Framework 1.1 voraussetzt

zu 3.) nicht unser Problem, wenn wir jedes Mal darauf eingehen würden, im Batch-Bereich, hätten wir so einiges nicht geschnipselt, die Meisten wollen nur auslesen und für .csv XYZ tabellarisch aufführen ...

Ja, wer hat hier was gespart, 10min für ein Programm (ohne Download- und Installationszeit), das der TE auch nicht hinbekommen hätte und hier 3 Stunden eine endgültige Lösung gesucht hätte ... oder 27 Sekunden für eine Batchzeile, folgend aus einer anderen ... 3 Stunden, weil's kein Live-Chat-Support ist und weder der TE noch wir instant-messages raushauen ...

Mann, was willst du uns erzählen? Dein Zwei-Zeilen-Spruch war schon Gepose genug, darfst dich wieder aus dem Batch-Bereich entfernen.
Member: bastla
bastla Apr 05, 2012 at 09:34:20 (UTC)
Goto Top
Hallo Skye!

Dass Du Dich gar so echauffieren magst ... face-wink

Abseits der vollmundigen Ansage von Weiricth ließe sich das natürlich durchaus mit nur ein paar Codezeilen umsetzen - etwa:
Sub Main(ByVal Args As String())
Dim suchtext As String = Args(0)
Dim p_DateinameInklPfad As String = Args(1)
Dim p_text As String()
Try
    p_text = Split(My.Computer.FileSystem.ReadAllText(p_DateinameInklPfad), vbNewLine)
Catch ex As Exception
    Environment.ExitCode = 1
    Exit Sub
End Try
Dim myRegex As New System.Text.RegularExpressions.Regex(suchtext)
For i As Integer = 0 To p_text.Length - 1
    If myRegex.IsMatch(p_text(i)) Then Console.WriteLine(p_text(i))
Next
End Sub
wobei allerdings noch zumindest für die Aufrufparameter Überprüfung/Errorhandling zu ergänzen wäre ...
Was noch hinzukäme: Ich mag nicht glauben (aber auch nicht testen face-wink), dass sich damit gegenüber einem "findstr" tatsächlich eine bessere Performance erzielen ließe ...

[Edit] Um aber zumindest noch einen Vorteil zu nennen: Mit einer leichten Modifikation würde das Ergebnis nicht mehr ganze Zeilen, sondern nur noch die dem Suchbegriff entsprechenden Strings umfassen:
Sub Main(ByVal Args As String())
Dim suchtext As String = Args(0)
Dim p_DateinameInklPfad As String = Args(1)
Dim p_text As String

Try
    p_text = My.Computer.FileSystem.ReadAllText(p_DateinameInklPfad)
Catch ex As Exception
    Environment.ExitCode = 1
    Exit Sub
End Try
Dim myRegex As New System.Text.RegularExpressions.Regex(suchtext)
For Each Match In myRegex.Matches(p_text)
    Console.WriteLine(Match)
Next
End Sub
Aufzurufen wäre dann mit dem Suchbegriff
"Benutzername : *ABC\S*"
um als Ergebnis "Benutzername : " + Leerzeichen + ABC" + alle bis zum nächsten "Whitespace" (also Leerzeichen, TAB, Zeilenschaltung) folgenden Zeichen zu erhalten.

Auch "Benutzername :" und die folgenden Leerzeichen ließen sich durch Verwendung eines SubMatches noch leicht eliminieren:
Console.WriteLine(Match.Groups(1))
und Suchbegriff
"Benutzername : *(ABC\S*)"
[/Edit]

Grüße
bastla
Member: dedalus2011
dedalus2011 Apr 05, 2012 at 11:42:52 (UTC)
Goto Top
Hallo bastla,

in der automatisch generierten Protokolldatei in der auf diese Sequenz durchsucht werden soll kommt auch das Pipe-Symbol vor, was dafür sorgt, dass das Programm abbricht sobald findstr diese Zeile parst

z.B. die Zeile sieht ungefähr so aus: "|Prozedur UNLOAD Zeile 206 (ohne das Anführungszeichen, bricht das Programm nicht ab!)

Im Programm selbst wird Pipelining verwendet, z.b:

 echo "%Zeile%"|findstr /i /r /c:"Benutzername : *ABC">nul   
Was kann man dagegen tun?

Grüße
dedalus2011
Member: bastla
bastla Apr 05, 2012 at 12:09:07 (UTC)
Goto Top
Hallo dedalus2011!

Versuch es so:
echo "%Zeile:|=%"|findstr /i /r /c:"Benutzername : *ABC">nul
bzw mit
setlocal enabledelayedexpansion
echo !Zeile!|findstr /i /r /c:"Benutzername : *ABC">nul  
endlocal
Allerdings ist eine ungerade Anzahl von Anführungszeichen meist ohnehin heikel ...

Grüße
bastla