how to copy multiple line from text file C# - c#

I need to copy multiple lines from text file(cisco config file): based on the below condition
if the line starts with interface copy from interface until '! '
my file is like :
!
access-list 1>
!
interface 1
ip address xx.xx.xx.xx
!
interface 2
ip address xx.xx.xx.xx
!
route 1
!
I try the below code :
var lines = File.ReadAllLines("C:\\My File2.txt");
foreach (var line1 in lines){
string firstWord = line1.Split(' ').First();
if ((firstWord == "access-list") && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (firstWord == "nat")
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
else if (firstWord == "interface")
{
var result = lines.Substring(line1.LastIndexOf('!') + 1);
TextBox3.Text = TextBox3.Text + "\r\n" + result;
}
but I get only one line as output

In case you want to keep your algorithm, this will work for you.
var lines = File.ReadAllLines("C:\\My File2.txt");
int i;
for (i = 0; i<lines.Length;i++)
{
var line1 = lines[i];
if (line1 == "!" || line1 == " ") continue;
if (line1.StartsWith("access-list")) && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (line1.StartsWith("nat"))
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
if (line1.StartsWith("interface"))
{
var str = line1;
while (!Equals(lines[i + 1], "!"))
{
str += lines[i + 1];
i++;
}
TextBox3.Text = TextBox3.Text + "\r\n" + str;
}
}

As per the file structure shown by you interface and ip address are on different lines. So you won't get it in same iteration of for loop. When you find that firstWord == "interface" you will need to set a flag that will tell you that next line is ip address and in next iteration check if that flag is true parse the current line as ip address and process it the way you want.

You should use "File.ReadAllText" instead of "File.ReadAllLines". "File.ReadAllText" returns a string with the complete text file text. After that, you can use the "String.Split" method to generate a string array.
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
Each index of "seperatedStrings" contains what you want.
UPDATE: Here is a code snippet, that can help:
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
foreach (var oneString in seperatedStrings)
{
if (oneString.Contains("access-list"))
{
Console.WriteLine("Access-List: " + oneString);
}else if (oneString.Contains("nat"))
{
Console.WriteLine("Nat: " + oneString);
}else if (oneString.Contains("interface"))
{
Console.WriteLine("Interface: " + oneString);
}
}
This is the output of my code snippet:

Related

How can I do a header for a CSV using StringBuilder? C#

I will edit my post because I couldn't express very well.
I want to do this:
This
And I don't know how to do a unique header. I achieved this:
Achieved
but now I need to do the header. I will post more of my code here:
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < Shift)
return;
string header = "Time" + ";" + "Close[0]" + ";" + "ATR_7" + ";" + "VOL_7" + ";" + "LABEL";
string Label = "NULL";
if(Alcista)
{
if(Open[0] >= Open[Shift - 1] && Open[0]/Open[Shift - 1] >= 1.0001)
{
Label = "UP";
}
else
{
Label = "DOWN";
}
}
switch(Indicar2_Sesgo)
{
case Sesgo.Alcista:
StringBuilder csvcontent = new StringBuilder();
csvcontent.AppendLine(Convert.ToString(Times[0][0].TimeOfDay + ";" + Close[0] + ";" + ATR1[0] + ";" + VOL1[0] + ";" + Label));
string csvpath = "D:\\xyz.csv";
File.AppendAllText(csvpath, csvcontent.ToString());
break;
}
}
It is a little difficult to know what your output is supposed to look like, but if you are simply trying to write a header, your code may look something like this:
var csvPath = "D:\\xyz.csv";
var csvHeader = "Time;Close;Atr1;Atr2";
File.WriteAllText(csvPath, csvHeader + Environment.NewLine);
As others have mentioned you would be better off using a helper library (like csvhelper) and setting the delimiter to a semicolon.

ArgumentOutOfRangeException when I think my code should work

I'm working on a bit of code for school but I keep getting an ArgumentOutOfRangeException
With this code I'm trying to read some data from a .csv file and if it equals the name of the image I want it to remove it from the .csv file whilst keeping the structure intact.
public void checkPair(Image card1, Image card2)
{
this.Image1 = card1;
this.Image2 = card2;
if (Convert.ToString(card1.Source) == Convert.ToString(card2.Source) && (card1 != card2))
{
getPoint(card1, card2);
string path = #"Save1.csv";
var reader = new StreamReader(File.OpenRead(path));
var data = new List<List<string>>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
data.Add(new List<String> { values[0], values[1]
});
}
reader.Close();
string delimiter = ";";
for (int i = 1; i < 5; i++)
{
for (int x = 0; x < 4; x++)
{
if (data[i][x] == Convert.ToString(card1.Source))
{
data[i][x] = null;
}
}
}
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] + Environment.NewLine + data[1][0] + delimiter + data[1][1] + delimiter + data[1][2] + delimiter + data[1][3] + Environment.NewLine + data[2][0] + delimiter + data[2][1] + delimiter + data[2][2] + delimiter + data[2][3] + Environment.NewLine + data[3][0] + delimiter + data[3][1] + delimiter + data[3][2] + delimiter + data[3][3] + Environment.NewLine + data[4][0] + delimiter + data[4][1] + delimiter + data[4][2] + delimiter + data[4][3] + Environment.NewLine + "ready");
I have no idea why I get this error and how to fix it
Initially, I'd change your last line from
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] ....
to something like
var obj1 = data[0][0];
var obj2 = data[0][1];
File.WriteAllText(path, obj1 + delimiter + obj2 .... etc)
If you over inline functions or array accessing, when you get an exception the stack trace won't be that helpful. At least you'll have an idea of the statement that caused the issue.
This technique can prove to be very helpful, if you are looking at an in exception in the logs, after the fact.

Taglib array exception when setting Artist field

I keep getting an array out of bounds exception with Taglib.tag.Performers in this function that edits ID3 data. I read elsewhere that clearing tag.performers[] can help (if null) but I still get the error sometimes.
Error message:
"Index was outside the bounds of the array.Data:
'System.Collections.ListDictionaryInternal' for test.mp3"
var fileArr = Directory.GetFiles(BasePath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".mp3") || s.EndsWith(".m4a")).ToArray();
foreach (var file in fileArr)
{
string fileName = Path.GetFileName(file);
string tagArtist = "";
string tagTitle = "";
string tempRegFilename = fileName;
string title = "";
//Apply to tag
TagLib.File mp3tag = TagLib.File.Create(file);
if (mp3tag.Tag.Title != null && mp3tag.Tag.Title.Length > 1)
{
title = mp3tag.Tag.Title;
}
else
{
mp3tag.Tag.Title = String.Empty;
}
if (mp3tag.Tag.Performers[0].Length < 1 || mp3tag.Tag.Performers[0] == null)
{
mp3tag.Tag.Performers[0] = null;
mp3tag.Tag.Performers = new[] { String.Empty };
mp3tag.Save();
}
if (mp3tag.Tag.Performers[0].Length > 1)
{
string[] performers = mp3tag.Tag.Performers;
if (title.Length > 2 && performers[0].Length > 1)
{
tagTitle = title;
tagArtist = performers[0].ToString();
Log.Info("ID3 Artist: " + "[" + tagArtist + "]");
Log.Info("ID3 Title: " + "[" + tagTitle + "]");
Log.Info("Tag data OK");
}
}
//Get artist from filename
if (mp3tag.Tag.Performers[0].Length < 1 || mp3tag.Tag.Performers == null)
{
mp3tag.Tag.Performers = new[] { String.Empty };
string prevArtist = String.Empty;
if (tempRegFilename.Contains("-"))
{
Log.Info("Artist data missing...");
string[] words = tempRegFilename.Split('-');
{
words[0] = words[0].Trim();
string perf = words[0];
mp3tag.Tag.Performers = new[] { perf };
Log.Info("Artists changed from \'" + prevArtist + "\' to " + "'" + perf + "'" + "\r\n");
mp3tag.Save();
}
}
mp3tag.Save();
}
}
catch (Exception ex)
{
Log.Error("TAG EXCEPTION: " + ex.Message + "Data: " + "'" + ex.Data + "'" + " for " + fileName + "\r\n" + ex.HelpLink);
}
Can anyone see what's wrong? I don't have much experience and could use the help. Thanks.
You seem to be assuming in a number of places that mp3Tag.Tag.Performers will have at least one element in it. If it doesn't, then you'll get the exception that you mention whenever you try to access mp3tag.Tag.Performers[0]
It looks like you may be trying to catch that possibility with this code:
if (mp3tag.Tag.Performers[0].Length < 1 || mp3tag.Tag.Performers[0] == null)
{
mp3tag.Tag.Performers[0] = null;
mp3tag.Tag.Performers = new[] { String.Empty };
mp3tag.Save();
}
But your logic is incorrect: you're getting the first element from the array (apparently a string) and checking its length, instead of checking the length of the array itself. Try this:
if (mp3tag.Tag.Performers.Length < 1 || mp3tag.Tag.Performers[0] == null)
{
mp3tag.Tag.Performers = new[] { String.Empty };
mp3tag.Save();
}
PS: It'll be much easier for you to see where your errors are if your log includes the stack trace of the exception, rather than just its message. I typically find it best to just use the ToString() on the exception itself.

Can only display array by iterating through a for loop

Hello I am trying to make a C# program that downloads files but I am having trouble with the array.
I have it split up the text for downloading and put it into a 2 level jagged array (string[][]).
Now I split up the rows up text by the | char so each line will be formatted like so:
{filename}|{filedescription}|{filehttppath}|{previewimagepath}|{length}|{source}
when I use short test text to put it into a text box it displays fine in the text box.
IE: a string like test|test|test|test|test|test
but if I put in a real string that I would actually be using for the program to DL files the only way I get the string to display is to iterate through it with a for or foreach loop. If I try to access the data with the index I get an index missing error. (IE array[0])
So this is the code that gets the array to display:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
}
And then this is the code that gives an index missing error:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
textBox1.Text = textBox1.Text + i[0] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[1] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[2] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[3] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[4] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[5] + Environment.NewLine;
}
}
Any help is this is apreciated I don't see why I can access they data through a for loop but not directly it just doesn't make any sense to me.
Also, here is the code that generates the array:
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i<FinalArray.Length;i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}
In your first example you are using the actual length of each inner array to do the concatenation. In your second example you are hard coded to the same length yet you said in the intro it was a jagged array.
Can you show what your input text looks like?
you are not doing the same concatenation in first and second example so the resulting stings are very different.
first = "\r\n Crazy Video\r\n\\\\newline\r\nThis Video is absolutly crazy!\r\n\\\\newline\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\n\\\\newline\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n\\\\newline\r\n300\r\n\\\\newline\r\nhtt://fakeurl.fake \r\n\\\\newline\r\n"
second = "\r\n Crazy Video\r\nThis Video is absolutly crazy!\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n300\r\nhtt://fakeurl.fake \r\n"
using System;
using NUnit.Framework;
namespace ClassLibrary5
{
public class Class1
{
[Test]
public void test()
{
var temp = new[]
{
" Crazy Video|This Video is absolutly crazy!|htt://fakeurl.fake/vidfolder/video.flv|htt://fakeurl.fake/imgfolder/img.j‌​pg|300|htt://fakeurl.fake "
};
var final = finalList(temp);
var first = Form1(final, "path");
var second = Form2(final, "path");
Assert.IsTrue(first.CompareTo(second) == 0);
}
public string Form1(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
for (int j = 0; j < i.Length; j++)
{
textString = textString + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
return textString;
}
public string Form2(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
textString = textString + i[0] + Environment.NewLine;
textString = textString + i[1] + Environment.NewLine;
textString = textString + i[2] + Environment.NewLine;
textString = textString + i[3] + Environment.NewLine;
textString = textString + i[4] + Environment.NewLine;
textString = textString + i[5] + Environment.NewLine;
}
return textString;
}
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i < FinalArray.Length; i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}
}
}
Are you sure each String[] in string[][] textList has 6 elements?
Try to replace:
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
with:
for(int j=0;j<6;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
And see if you get the same result. Your middle one has different logic than your first one. To troubleshoot, first make the logic the same, and then continue troubleshooting from there.

String list remove

I have this code:
List<string> lineList = new List<string>();
foreach (var line in theFinalList)
{
if (line.PartDescription != "")
lineList.Add(line.PartDescription + " " + line.PartNumber + "\n");
else
lineList.Add("N/A " + line.PartNumber + "\n");
//
//This is what I am trying to fix:
if (lineList.Contains("FID") || lineList.Contains("EXCLUDE"))
// REMOVE THE item in the lineList
}
I am trying to go through theFinalList in a foreach loop and add each line to a new list called lineList.
Once added, I want to remove any entries from that list that contain the text "FID" or "EXCLUDE".
I am having trouble removing the entry, can someone help me?
why add them when you want to remove them right after:
lineList = theFinalList.Select( line =>
{
if (line.PartDescription != "")
return line.PartDescription + " " + line.PartNumber + "\n";
else
return "N/A " + line.PartNumber + "\n";
})
.Where(x => !(x.Contains("FID") || x.Contains("EXCLUDE")))
.ToList();
The following code sample iterates through the lineList and removes lines that contain FID or EXCLUDE.
for(int i = lineList.Count - 1; i >= 0; i--)
{
if (lineList[i].Contains("FID") || lineList[i].Contains("EXCLUDE"))
lineList.RemoveAt(i);
}
It is important to traverse a list in reverse order when deleting items.
You can't remove the items in your theFinalList list while you are iterating over theFinalList in a foreach loop. In this case, you may get System.InvalidOperationException with the message “Collection was modified; enumeration operation may not execute.”
you have to do something like this:
List<string> removals = new List<string>();
foreach (string s in theFinalList)
{
//do stuff with (s);
removals.Add(s);
}
foreach (string s in removals)
{
theFinalList.Remove(s);
}
try
foreach (var line in theFinalList)
{
string T = "";
if (line.PartDescription != "")
T = line.PartDescription + " " + line.PartNumber + "\n";
else
T = "N/A " + line.PartNumber + "\n";
if (!(T.Contains("FID") || T.Contains("EXCLUDE"))
lineList.Add (T);
}
I think its more logical approach
Regex exclude = new Regex("FID|EXCLUDE");
foreach (var line in theFinalList.Where(
ln => !exclude.Match(ln.PartDescription).Success &&
!exclude.Match(ln.PartNumber ).Success))){
string partDescription = "N/A";
if(!string.IsNullOrWhiteSpace(line.PartDescription)){
partDescription = line.PartDescription;
}
lineList.Add(partDescription + " " + line.PartNumber + "\n");
}
edit regex for your needs (ignore case maybe or multiline, probably compiled too) and feel free to replace "\n" with Environment.NewLine
Try this:
var excludingTexts = new [] { "FID", "EXCLUDE" }
lineList = lineList.Where(y => !excludingTexts.Any(x => line.PartDescription.Contains(x) || line.PartNumber.Contains(x))).ToList();
Or you can rewrite it as:
var excludingTexts = new [] { "FID", "EXCLUDE" }
List<string> lineList = (from line in theFinalList
where !excludingTexts.Any(x => line.PartDescription.Contains(x) || line.PartNumber.Contains(x))
select line.PartDescription != "" ?
line.PartDescription + " " + line.PartNumber + "\n" :
"N/A " + line.PartNumber + "\n"
).ToList();

Categories

Resources