In my project, I have a .csv file with many columns.
I need to extract all rows for only first column. I've managed to read all lines, but got stuck on how to extract rows from first column to another .csv file.
string filePath = #"C:\Users\BP185150\Desktop\OTC.csv";
string[] OTC_Output = File.ReadAllLines(#"C:\Users\BP185150\Desktop\OTC.csv");
foreach (string line in OTC_Output)
{
Console.WriteLine(line);
Console.Read();
}
Console.ReadLine();
Depending on what seperator your csv is using you can use the string.split() function.
e.g.
string firstItem = line.Split(',')[0];
Console.WriteLine(firstItem);
Adding them to a collection:
ICollection<string> firstItems = new List<string>();
string[] OTC_Output = File.ReadAllLines(#"C:\Users\BP185150\Desktop\OTC.csv");
foreach (string line in OTC_Output)
{
firstItems.Add(line.Split(',')[0]);
}
Well if you want to use File.ReadAllLines, the best way to get the first column is to split the line with a delimiter that your csv is using. Then just add the first item of every line to a collection.
var column = OTC_Output.Select(line => line.Split(';').First()).ToList();
In lineItems, you'll have all the columns splitted:
var lineItems = line.Split(";").ToArray();
Then, parse the value only for the first of them:
lineItems.GetValue(0).ToString();
Related
I am new to in C# need help to write parser for below cvs file of data
[INFO]
LINE_NAME,MACHINE_SN,MACHINE_NAME,OPERATOR_ID
LineName,ParmiMachineSN,PARMI_AOI_1,engineer
[INFO_END]
[PANEL_INSP_RESULT]
MODEL_NAME,MODEL_CODE,PANEL_SIDE,INDEX,BARCODE,DATE,START_TIME,END_TIME,DEFECT_NAME,DEFECT_CODE,RESULT
E11-03356-0388-A-TOP CNG,,BOTTOM,47,MLT0388A03358CSNSOF1232210200052-0001,20201023,12:46:57,12:47:04,,,OK
[PANEL_INSP_RESULT_END]
[BOARD_INSP_RESULT]
BOARD_NO,BARCODE,DEFECT_NAME,DEFECT_CODE,BADMARK,RESULT
1,MLT0388A03358CSNSOF1232210200052-0001,,,NO,OK
2,MLT0388A03358CSNSOF1232210200052-0004,,,NO,OK
3,MLT0388A03358CSNSOF1232210200052-0003,,,NO,OK
4,MLT0388A03358CSNSOF1232210200052-0002,,,NO,OK
[BOARD_INSP_RESULT_END]
[COMPONENT_INSP_RESULT]
BOARD_NO,LOCATION_NAME,PIN_NUMBER,POS_X,POS_Y,DEFECT_NAME,DEFECT_CODE,RESULT
[COMPONENT_INSP_RESULT_END]
I need to parse the above file
To parse the above CSV file in C#, you can use the following steps:
Read the entire file into a string using the File.ReadAllText method.
string fileText = File.ReadAllText("file.csv");
Split the file into individual sections by looking for the "[INFO]" and "
[INFO_END]" tags, and then use a loop to process each section.
string[] sections = fileText.Split(new string[] { "[INFO]", "[INFO_END]", "[PANEL_INSP_RESULT]", "[PANEL_INSP_RESULT_END]", "[BOARD_INSP_RESULT]", "[BOARD_INSP_RESULT_END]", "[COMPONENT_INSP_RESULT]", "[COMPONENT_INSP_RESULT_END]" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string section in sections)
{
//Process each section
}
Within the loop, use the String.Split method to split each section into rows by looking for the newline character.
string[] rows = section.Split('\n');
Use the String.Split method again to split each row into cells by looking for the comma.
foreach (string row in rows)
{
string[] cells = row.Split(',');
//Process each cell
}
Now you can process each cell as you need, you can check the first cell value to decide which section this row belongs to, and then you can process the cells according to their type and position in the row.
You can use a switch case statement to check which section you are currently processing and then use appropriate logic to parse the data.
Please be aware that this is a simplified example, and you may need to add additional error handling and validation to ensure that the data is properly parsed.
This is an example how you can parse the csv file but you might need to handle various edge cases like empty rows, empty cells, etc based on your specific use case.
The following reads all text, creates an anonymous list with line index and line followed by looping through a list of sections. In the loop find a section and in this case displays to a console window.
internal partial class Program
{
static void Main(string[] args)
{
var items = (File.ReadAllLines("YourFileNameGoesHere")
.Select((line, index) => new { Line = line, Index = index })
.Select(lineData => lineData)).ToList();
List<string> sections = new List<string>()
{
"INFO",
"PANEL_INSP_RESULT",
"BOARD_INSP_RESULT",
"COMPONENT_INSP_RESULT"
};
foreach (var section in sections)
{
Console.WriteLine($"{section}");
var startItem = items.FirstOrDefault(x => x.Line == $"[{section}]");
var endItem = items.FirstOrDefault(x => x.Line == $"[{section}_END]");
if (startItem is not null && endItem is not null)
{
bool header = false;
for (int index = startItem.Index + 1; index < endItem.Index; index++)
{
if (header == false)
{
Console.WriteLine($"\t{items[index].Line}");
header = true;
}
else
{
Console.WriteLine($"\t\t{items[index].Line}");
}
}
}
else
{
Console.WriteLine("\tFailed to read this section");
}
}
}
}
I have this code:
//new List
List<string> lines = new List<string>();
List<string> lines2 = new List<string>();
// read and write data to list
for (int i = 0; i < fileName.Length; i++)
{
string file = #"read\" + Path.GetFileName(fileName[i]);
// load rows to list.
lines = File.ReadLines(file).ToList();
foreach (string line in lines)
{
// Variablen für lines
string[] entries = line.Split(';');
int length = entries.Length;
}
}
I am able to read all lines from my csv file into one list but I would like to split the csv file after the 6th column into a second list. How do I do that?
I tired already linq with lines.Take(6).ToList(); but this just reads the first 6 lines if I'm not mistaken. Same for Skip().
You are on the right track, to use Take and Skip, and then to add the items to their respective lists, you can call the AddRange method to add a group of items at once:
var filePath = #"c:\public\temp\temp.txt";
var firstSixColumns = new List<string>();
var restOfColumns = new List<string>();
foreach(var fileLine in File.ReadLines(filePath))
{
var fileLineParts = fileLine.Split(';');
firstSixColumns.AddRange(fileLineParts.Take(6)); // Add the first 6 entries
restOfColumns.AddRange(fileLineParts.Skip(6)); // Add the rest of the entries
}
If, on the other hand, you are trying to just split the csv lines into two groups of columns, without splitting them further (so each line in firstSixLines would represent a row of six columns), then you can use string.Join to stitch the columns back again before adding them:
foreach(var fileLine in File.ReadLines(filePath))
{
var fileLineParts = fileLine.Split(';');
// Join the items before adding them to their respective lists
firstSixColumns.Add(string.Join(";", fileLineParts.Take(6)));
restOfColumns.Add(string.Join(";", fileLineParts.Skip(6)));
}
You need to apply skip at the point you are reading the column values
List<string> entries = line.Split(';').Skip(6).ToList();
That said there are plenty of libraries that you can use that are built around reading CSV files. I would recommend searching NuGet for one before you reinvent the wheel.
If you want 2 lists
string[] entries = line.Split(';');
List<string> entriesFirst = entries.Take(6).ToList();
List<string> entriesSecond = entries.Skip(6).ToList();
CSVHelper and FileHelper is not an option
I have a .csv export that I need to check for consistency structured like the below
Reference,Date,EntryID
ABC123,08/09/2015,123
ABD234,08/09/2015,124
XYZ987,07/09/2015,125
QWE456,08/09/2016,126
I can use ReadLine or RealAllLines and .Split which give me entire rows/columns BUT I have need to select each row and then go through each attribute (separated by ',') for format checking
I am running into problems here. I can not single out each value in a row for this check.
It is probably either something simple onto
class Program
{
static void Main(string[] args)
{
string csvFile = #"proof.csv";
string[] lines = File.ReadAllLines(csvFile);
var values = lines.Skip(1).Select(l => new { FirstRow = l.Split('\n').First(), Values = l.Split('\n').Select(v => int.Parse(v)) });
foreach (var value in values)
{
Console.WriteLine(string.Format("{0}", value.FirstRow));
}
}
}
Or I am going down the wrong path, my searches relate to pulling specific rows or columns (as opposed to checking the individual values associated)
The sample of the data above has a highlighted example: The date is next year and I would like to be able to proof that value (just an example as it could be in either column where errors appear)
I can not single out each value in a row
That's because you split on \n twice. The values within a row are separated by comma (,).
I'm not sure what all that LINQ is supposed to do, but it's as simple as this:
string[] lines = File.ReadAllLines(csvFile);
foreach (var line in lines.Skip(1))
{
var values = line.Split(',');
// access values[0], values[1] ...
}
Instead of reading it as text read it by OLEDB object, so data of CSV file will come in datatable and you do not need to spit it.
To Read the csv file you can use these objects of OLEDB
System.Data.OleDb.OleDbCommand
System.Data.OleDb.OleDbDataAdapter
System.Data.OleDb.OleDbConnection
and
System.Data.DataTable
Does anyone know how to convert a specific column in a csv file to string List ?
I am trying to have a 'contact number' list from csv file. (Please see my csv file in below)
Intending to do
List<string> contactNumberList = new List<string>();
-- contactNumberList.Add("1888714"); (Manual)
---contactNumberList.Add("1888759");(Manual)
In my CSV
"Email","Opt In Date","Opted Out","Opt In Details","Email Type","Opted Out Date","Opt Out Details","Contact Number","Salutation"
"test1#testApp.com","05/01/2014 11:23 AM","F","User Name: capn#goldpop.org.uk. IP Address: 62.213.118.139","0","","","1888714","Mrs Hall"
"test2#testApp.com","05/01/2014 11:23 AM","F","User Name: capntransfer#goldpop.org.uk. IP Address: 62.213.118.139","0","","","1888759","Mrs Heyworth"
For parsing CSVs I suggest using a ligrary a s simply splitting by line /columns separator can bring to errors if the values are escaped.
I.e.
"Mr John, Bob Smith"
is a valid CSV as it is escaped with quotes. But a Split function will stop working.
One valid choice is LumenWorks (you can find it in NuGet).
I.e.
using (var csv = new CsvReader(r, false, csvParserConfiguration.ColumnSeparator, '"', '"', '#', ValueTrimmingOptions.None))
{
// Read lines
while (csv.ReadNextRecord())
{
contactNumberList.Add[7];
}
}
Read the file line by line, Split() by commas, select the desired column, trim quotes off and add to a list?
Try this:
int columnId = 3;
string[] lines = File.ReadAllLines(#"C:\test.csv");
var list = lines.Select(line =>
{ var values = line.Split(';');
return values[columnId];
});
You could try the following:
var reader = new StreamReader(File.OpenRead(#"C:\test.csv"));
List<string> contactNumbersList = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
contactNumbersList.Add(values[7]);
}
but better yet you could use a dedicated library like CSV Reader.
IEnumerable<string> strings = System.IO.File.ReadAllLines({filepath})
.Select(x => x.Split(';')[{columnId}])
I'm working on an importer that takes tab delimited text files. The first line of each file contains 'columns' like ItemCode, Language, ImportMode etc and there can be varying numbers of columns.
I'm able to get the names of each column, whether there's one or 10 and so on. I use a method to achieve this that returns List<string>:
private List<string> GetColumnNames(string saveLocation, int numColumns)
{
var data = (File.ReadAllLines(saveLocation));
var columnNames = new List<string>();
for (int i = 0; i < numColumns; i++)
{
var cols = from lines in data
.Take(1)
.Where(l => !string.IsNullOrEmpty(l))
.Select(l => l.Split(delimiter.ToCharArray(), StringSplitOptions.None))
.Select(value => string.Join(" ", value))
let split = lines.Split(' ')
select new
{
Temp = split[i].Trim()
};
foreach (var x in cols)
{
columnNames.Add(x.Temp);
}
}
return columnNames;
}
If I always knew what columns to be expecting, I could just create a new object, but since I don't, I'm wondering is there a way I can dynamically create an object with properties that correspond to whatever GetColumnNames() returns?
Any suggestions?
For what it's worth, here's how I used DataTables to achieve what I wanted.
// saveLocation is file location
// numColumns comes from another method that gets number of columns in file
var columnNames = GetColumnNames(saveLocation, numColumns);
var table = new DataTable();
foreach (var header in columnNames)
{
table.Columns.Add(header);
}
// itemAttributeData is the file split into lines
foreach (var row in itemAttributeData)
{
table.Rows.Add(row);
}
Although there was a bit more work involved to be able to manipulate the data in the way I wanted, Karthik's suggestion got me on the right track.
You could create a dictionary of strings where the first string references the "properties" name and the second string its characteristic.