Laden...

Mehrere Zeilen mit bestimmten "Wörtern" Werten in Textdatei finden und in eine andere kopieren

Erstellt von BlutigerAnfänger2 vor 3 Jahren Letzter Beitrag vor 3 Jahren 968 Views
B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren
Mehrere Zeilen mit bestimmten "Wörtern" Werten in Textdatei finden und in eine andere kopieren

Hallo zusammen,

ich bin Neu hier im Forum. Zu meinen Thema suche ich bereits seit Tagen und habe auch schon einige Scripte Versucht, bis jetzt alles erfolglos. Wenn es das Thema schon zu genüge geben sollte, oder ähnliches, bitte einfach wieder löschen.

zu meinem Prblem / meiner Frage:

ich habe eine Textdatei mit Werten die ich von einer Cisco Switch Abfrage erstellt. Nun ist in der Textdatei natürlich viel Mist drin, den ich nicht brauche.

die Textdatei sieht wie folgt aus:

KDE-PO-SW01#show interface switchport GE 1
Added by: D-Default, S-Static, G-GVRP, R-Radius Assigned VLAN, T-Guest VLAN, V-Voice VLAN
Port : gi1
Port Mode: Access
Gvrp Status: disabled
Ingress Filtering: true
Acceptable Frame Type: admitAll
Ingress UnTagged VLAN ( NATIVE ): 1
Port is member in:
Vlan Name Egress rule Added by


usw. pro Port eine solche Ausgabe. Bei diesem Switch sind das 28 Ports.

ich benötige nur die Information Port : gi1 + Port Mode: Access

sollte fertig am besten so aussehen:
Port : gi1 ; Access
Port : gi2 ; Access
Port : gi3 ; Trunk
...

wie ist mir eigentlich egal ob jetzt in einer neuen Datei die Werte gespeichert werden, oder alles in der hier löschen bis auf die Werte die ich benötige.

Ich wäre ich für den Vorschlag und für jede Hilfe dankbar. Ich weis es ist bestimmt sehr simple, aber ich verzweifel gerade daran. Habe es mit Regex versucht, mit Streamreader - Startswith(), etc.

Vielen Dank schon mal im voraus

16.807 Beiträge seit 2008
vor 3 Jahren

Was ist denn die Frage? Was hast Du versucht? Wo kommst Du nicht weiter?
Ich hoffe doch Du erwartest nicht, dass wir Dir nun den Code schreiben 😃

M
368 Beiträge seit 2006
vor 3 Jahren

Von C# mal abgesehen, kann man sich an Perl i.V. mit dem Modul Tie::File probieren. Aus der Textdatei dann die passenden Zeilen (vrmtl. 3. und 4. sowie plus x bei nachfolgenden Ergebnissen) extrahieren lassen.

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren

Hallo Abt, danke für die sehr schnelle Antwort.

Nein, mir geht es nicht darum das mir jemand den Quellcode schreibt (ich habe die Regeln zum erstellen eines Threads gelesen). Es geht mir um einen Denkanstoß, evtl eine andere Sichtweise.
An irgendwas müssen meine Versuche gescheitert sein.

Ich werde in Zunkunft öfter vor diesem Problem stehen, daher will ich es auch verstehen. Ich komme aus der SQL Welt, da wäre so eine Abfrage ein Kinderspiel. Die Datei ist nur ein Zwischenschritt, danach kommt noch eine Abfrage an den Switch per C#, ist diese erfolgt geht es mit der Datenbank Einbindung weiter.

Ich habe bisher versucht die Textdatei Zeilenweise bis "EOF" oder auch bis "isnullorempty" einzulesen und darin die abfrage mit "Startswith" versucht, dann das gleiche mit readalltext und readallline....

...vielleicht liegt hier im Vorgehen mein Fehler.

Ich fand hierzu leider auch in meinen C# Büchern nichts.

Nochmal bitte...es geht mir nicht um den Quellcode, sondern mehr um eine andere Sichtweise, wie ich das Problem angehn könnte, oder evtl eine Klasse, die dafür besser geeignet ist.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Wie sieht den der aktuelle Code von dir aus?
An sich bist du mit dem zeilenweise einlesen schon auf dem richtigen Weg.
Wobei du aber die Datei bis zum EOF lesen solltest oder gibt es den Fall mit einer leeren Zeile nie bei dir?

Ansonsten sollte auch StartsWith bei der Zeile mit "Port :" und "Port Mode: " die entsprechenden Informationen liefern.
Hier wäre also die Frage woran es scheitert.
Solltest du auch durch debuggen einfach finden können.
Falls noch nicht druckbare Sonderzeichen o.ä. am Zeilenanfang wären, würde es erklären warum es nicht funktioniert.
Aber auch dies liese sich ggf. mit einem entsprechenden Editor prüfen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren

Hallo T-Virus,

danke für Deine Hilfe...ich habe es geschafft. Der Fehler lag bei den Leerzeilen. Die habe ich jetzt entfernt und schon lief es durch.

hier mein Code:

string path = @"C:\Desktop\Test.txt";
string path2 = @"C:\Desktop\Test.txt";
StreamReader sr = new StreamReader(path);
while (!sr.EndOfStream)
{
	var line = sr.Readline();
	if (line.StartsWith("Port :") || line.StartsWith("Port Mode")
	{
		StreamWriter sw = File.AppendText(path2);
		sw.WriteLine(line);
		sw.Close();
	}
}

Jetzt sieht meine Textdatei so aus:

Port : gi1
Port Mode: Access
Port : gi2
Port Mode: Access
usw.

Hast du evtl noch einen Tipp wie meine Textdatei so hinbekomme:?

gi1 : Access
gi2 : Access
usw.

Dazu müsste ich sie jetzt Splitten oder? Aber geht das horizontal?

4.931 Beiträge seit 2008
vor 3 Jahren

Die übliche Leseroutine sieht so aus:


string line;
while ((line = sr.Readline()) != null)
{
  // ...
}

(bei deiner könnte es passieren, daß in der Schleife line zu null wird, und dann müßtest du noch extra auf != null abfragen, damit es nicht zu einer NullReferenceException kommt)

Für deine Port-Werte lege dir eine eigene Klasse (oder Struktur) dafür an:


class PortData
{
  public string Name { get; set; }
  public string Mode { get; set; }
}

Nun legst du dir eine Variable davon vor der Schleife an: PortData portData = new PortData() und füllst dann die einzelnen Eigenschaften passend.
Immer wenn du alle Werte hast (oder je nach Szenario, wenn ein neuer Port-Name gelesen wird), schreibst du diese Portdaten raus und löschst diese Daten (schreibe dir z.B. eine Methode Clear() oder lege eine neues PortData-Objekt an).
Und dann nach der Schleife noch mal einmalig die letzten Portdaten ausgeben.

PS: Splitten kannst du mittels String.Split (z.B. anhand des :) oder über den Index mittels String.Substring.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Ich würde den Ansatz von Th69 noch etwas verfeiern.
Sammle die PortData Einträge in einer Liste.
Wenn du einen neuen Port hast, legst du einen neuen Eintrag mit der Portnummer an und füst diesen in die Liste ein.
Dann musst du nur den Port Mode noch auslesen und dem aktuellen Objekt zuweisen.

Zum schluss kannst du die Einträge aus deiner Liste in einem Rutsch wegschreiben.
Das spart unnötigen Overhead durch häufiges öffnen und schreiben in die Datei pro Eintrag und du trennst gleich den Code zum auslesen und zum schreiben sauber weg.

Ebenfalls solltest du deinem StreamWriter entweder in ein using packen oder direkt per Dispose() Aufruf sauber wegräumen lassen!
using solltest du hier vorziehen.
Den Part kannst du dann auch in einer Write Methode wegkapseln.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren

Hallo,

Vielen Dank euch beiden. Versuche gerade Euere Tipps so gut wie möglich umzusetzen. 😁

Mein Code sieht derzeit so aus:

string path = @"C:\Desktop\Test.txt";
string path2 = @"C:\Desktop\Test2.txt";
StreamReader sr = new StreamReader(path);
string line;
//while (!sr.EndOfStream)
while ((line = sr.Readline()) != null)
{
	//var line = sr.Readline();
	if (line.StartsWith("Port :") || line.StartsWith("Port Mode")
	{
		var werte = line.Split(new char[] { ':' });
		string einzelwerte = werte[1];
		using(StreamWriter sw = File.AppendText(path2))
		{
			sw.WriteLine(einzelwerte);
			sw.Close();
		}
	}
}

Klappt auch in meinem Hauptprogramm wunderbar.

Meine Textdatei ausgabe sieht derzeit so aus:

gi1
Access
gi2
Access
gi3
Access

string.split habe ich soweit umsetzen können, aber mit dem zusammen führen sehe ich bei string.substring nicht. Wie ich den string.substring interpretiere, kann ich damit einzelne Wörter/Zeichen auch einem String herausnehmen und einen neuen String zusammensetzen. Aber aus zwei Zeilen eine Zeile machen 🤔

Ich bin euch wirklich sehr Dankbar, Ihr habt mir schon sehr viel weitergeholfen und ich habe wieder eine Menge dazugelernt.

4.931 Beiträge seit 2008
vor 3 Jahren

Wie schon geschrieben, darfst du nicht sofort je Zeile den Wert ausgeben, sondern mußt ihn erst intern sammeln.

Und mit Substring wird auch nicht zusammengeführt, sondern ein bestimmter Teilstring (anhand Position und Länge) extrahiert, aber Split ist hier wohl besser (sofern in den Daten selbst kein Doppelpunkt ':' steht, denn dann würdest du mit werte[1] nur den vorderen Teil der Daten erhalten).

B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren

Hallo,

nein, in den Daten selbst ist kein ":" . Sie sehen immer gleich aus, wie oben Aufgezeigt. Die
Ausgabe so wie sie jetzt ist würde mir schon passen (kein Schnick-schnack mehr), nur müssten jetzt die Werte in einer Zeile stehen, zum weiterverarbeiten.

wie z.B.

gi1; Access
gi2; Access
...usw.

dann wäre es perfekt. 👍 😁

5.657 Beiträge seit 2006
vor 3 Jahren
sw.WriteLine(einzelwerte);  

WriteLine schreibt einen Zeilenumbruch nach der Zeichenkette in den Stream, daher kommt der Zeilenumbruch. Du schreibst also selbst den Zeilenumbruch jedesmal in die Datei!

Was du dagegen tun kannst, hat dir Th69 ja bereits geschrieben.

Weeks of programming can save you hours of planning

B
BlutigerAnfänger2 Themenstarter:in
10 Beiträge seit 2020
vor 3 Jahren

Ich habe meine saubere CSV jetzt hinbekommen. Sie sieht aus, wie ich sie wollte:

gi1;Access
gi2;Access
...usw.

Nochmals vielen Dank an alle die mir geholfen haben. Ohne euch würde ich mich jetzt noch im Kreis drehen. 👍 😁