Remove blank lines in a text file - c#

How can you remove blank lines from a text file in C#?

If file is small:
var lines = File.ReadAllLines(fileName).Where(arg => !string.IsNullOrWhiteSpace(arg));
File.WriteAllLines(fileName, lines);
If file is huge:
var tempFileName = Path.GetTempFileName();
try
{
using (var streamReader = new StreamReader(inptuFileName))
using (var streamWriter = new StreamWriter(tempFileName))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
if (!string.IsNullOrWhiteSpace(line))
streamWriter.WriteLine(line);
}
}
File.Copy(tempFileName, inptuFileName, true);
}
finally
{
File.Delete(tempFileName);
}

File.WriteAllLines(path, File.ReadAllLines(path).Where(l => !string.IsNullOrWhiteSpace(l)));

Read all of the contents of a file into a string then just run
string output = null;
try {
output = Regex.Replace(input, #"^\s*$", "", RegexOptions.Multiline);
} catch (Exception e) {
}
Other similar options can be found in How to remove empty lines from a formatted string?

We can achieve it very easily by using LINQ technique for Huge or small file.
1.Explanation: It will read the file and skip all empty lines and store all the data into an string array
string[] text = File.ReadAllLines(path with file name).Where(s => s.Trim() != string.Empty).ToArray();
It will delete that file.
File.Delete(path with file name);
It will create new file as same name and append all the array data into new file
File.WriteAllLines(path with file name, text);
Complete Code
string[] text = File.ReadAllLines(LoraWan_Parameter_Check_Tool.Properties.Settings.Default.csv_file_path.ToString()).Where(s => s.Trim() != string.Empty).ToArray();
File.Delete(LoraWan_Parameter_Check_Tool.Properties.Settings.Default.csv_file_path.ToString());
File.WriteAllLines(LoraWan_Parameter_Check_Tool.Properties.Settings.Default.csv_file_path.ToString(), text);
Problem solved
Thank you

Related

How do I delete all lines in text file below certain text?

I have a code which iterates through the entire text file searching for a specific text "[names]", and "tried" to delete all the lines below the text. I tried File.WriteAllText(INILoc, string.Empty);, but this just deletes everything in the entire text file. How do I make it so only all the lines below "[names]" gets deleted?
I have set up the iteration likes this :
string[] lines = File.ReadAllLines(INILoc);
bool containsSearchResul = false;
foreach (string line in lines)
{
if (containsSearchResul)
{
File.WriteAllText(INILoc, string.Empty);
}
if (line.Contains("[names]"))
{
containsSearchResul = true;
}
}
You need to store lines before "[names]" text into a string variable, and when condition (line.Contains("[names]")) satisfy then just break the loop and write string value into the same file.
Something like,
string[] lines = File.ReadAllLines(INILoc); //Considering INILoc is a string variable which contains file path.
StringBuilder newText = new StringBuilder();
bool containsSearchResul = false;
foreach (string line in lines)
{
newText.Append(line);
newText.Append(Environment.NewLine); //This will add \n after each line so all lines will be well formatted
//Adding line into newText before if condition check will add "name" into file
if (line.Contains("[names]"))
break;
}
File.WriteAllText(INILoc, newText.ToString());
//^^^^^^^ due to string.Empty it was storing empty string into file.
Note: If you are using StringBuilder class, then do not miss to add Using System.Text in your program
Use StreamReader as it will give you the best performance as you don't need to read the whole file. Swap 'PATH TO INPUT FILE' with your file path and the result will be stored at the path you provide for 'PATH TO OUTPUT FILE'.
using (var sr = new StreamReader("PATH TO INPUT FILE"))
{
using (var sw = new StreamWriter("PATH TO OUTPUT FILE"))
{
var line = sr.ReadLine();
while (line != null)
{
sw.WriteLine(line);
if (line.Contains("[names]"))
{
sw.Close();
sr.Close();
}
else
{
line = sr.ReadLine();
}
}
}
}
If you need to write to the same file:
var sb = new StringBuilder();
using (var sr = new StreamReader("PATH TO INPUT FILE"))
{
var line = sr.ReadLine();
while (line != null)
{
sb.AppendLine(line);
if (line.Contains("[names]"))
{
sr.Close();
}
else
{
line = sr.ReadLine();
}
}
}
File.WriteAllText("PATH TO INPUT FILE", sb.ToString());
Based on the requested code I have put together modifications.
string[] lines = File.ReadAllLines(INILoc);
//create a list to hold the lines
List<string> output = new List<string>();
//loop through each line
foreach (string line in lines)
{
//add current line to ouput.
output.Add(line);
//check to see if our line includes the searched text;
if (line.Contains("[names]"))
{
//output to the file and then exit loop causing all lines below this
//one to be skipped
File.WriteAllText(INILoc, output.ToArray());
break;
}
}
The problem with your code is that it delete all the lines before the [names], not after (more exactly, write only the lines after that text). Also, any time you rewrite all the file content, and so remove all previous wrote line. It'll work as follows:
string[] lines = File.ReadAllLines(INILoc);
using (StreamWriter writer = new StreamWriter(INILoc)) // https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
{
bool containsSearchResul = false;
foreach (string line in lines)
{
if (!containsSearchResul)
{
writer.Write(INILoc, string.Empty);
}
if (line.Contains("[names]"))
{
containsSearchResul = true;
}
}
}
You have another, better option to do this with break:
string[] lines = File.ReadAllLines(INILoc);
using (StreamWriter writer = new StreamWriter(INILoc)) // https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
{
foreach (string line in lines)
{
if (line.Contains("[names]"))
{
break;
}
writer.WriteLine(INILoc, string.Empty);
}
}
But you can do this in prefered, more-readable way, by using LINQ:
using System.Linq;
// ...
string[] lines = File.ReadAllLines(INILoc);
string[] linesTillNames = lines
.Take( // Take just N items from the array
Array.IndexOf(lines, "[names]") // Until the index of [names]
)
.ToArray();
File.WriteAllLines(INILoc, linesTillNames);
You can also use: WriteAllLines(string path, IEnumerable<string> contents) like this:
string[] lines = File.ReadAllLines(INILoc);
List<string> linesToWrite = new List<string>();
foreach(string line in lines)
{
linesToWrite.Add(line);
if (line.Contains("[names]")) break;
}
File.WriteAllLines(INILoc, linesToWrite);

C# excel color text

I'm currently using the below code to compare two csv files with each other. I can select a column in the file and it will compare the rows in that column, it then writes the incorrect and correct rows into another csv file. But now I want to change the color the text 'this row is not the same' so that it's more noticeable. How can I do this?
public void comparing(int selectedRow, string filenaname, string filename2)
{
List<string> lines = new List<string>();
List<string> lines2 = new List<string>();
try
{
StreamReader reader = new StreamReader(System.IO.File.OpenRead(filename));
StreamReader read = new StreamReader(System.IO.File.OpenRead(filename2));
List<string> lijnen = new List<string>();
string line;
string line2;
string differencesFile= #"C:\Users\Mylan\Desktop\differences.csv";
while ((line = reader.ReadLine()) != null && (line2 = read.ReadLine()) != null)
{
string[] split = line.Split(Convert.ToChar(csvSeperator));
string[] split2 = line2.Split(Convert.ToChar(csvSeperator));
if (split[selectedRow] != split2[selectedRow])
{
lijnen.Add("This row is not the same:, " + line);
}
else if(test == test2)
{
System.Windows.Forms.MessageBox.Show("The whole file is the same");
break;
}
else
{
lines.Add("This row is the same:, " + line);
}
}
System.IO.File.WriteAllLines(differencesFile, lines);
System.Diagnostics.Process.Start(differencesFile);
reader.Dispose();
read.Dispose();
}
catch
{
}
}
}
}
I think it's impossible to do what you want with CSV files. Excel reads only the values and separate these in columns, that's all.
If you want to create an Excel file directly by code, you need to use for example the Open XML :
https://msdn.microsoft.com/en-gb/library/office/bb448854.aspx
This is what I use to create, edit Excel files (and Powerpoint files too). It's a bit tricky at beginning but it's a solution...

Only write data to text file if the line doesnt match any others

I want to add data into a text file based on a specific output. It will read an XML file and write a certain line to a text file. If the data is already written into the text file, I don't want to write it again.
Code
public void output(string folder)
{
string S = "Data" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xml";
//Trades.Save(S);
string path = Path.Combine(folder, S);
Console.WriteLine(path);
XDocument f = new XDocument(Trades);
f.Save(path);
string[] lines = File.ReadAllLines(path);
File.WriteAllLines(path, lines);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(
#"H:\Test" + DateTime.Now.ToString("yyMMdd") + ".txt", true))
{
foreach (string line in lines)
{
if (line.Contains("CertainData"))
{
file.WriteLine(line);
if (File.ReadAllLines(path).Any(x => x.Equals(line)))
{
}
else
{
string[] tradeRefLines = File.ReadAllLines(path);
File.WriteAllLines(path, tradeRefLines); ;
}
}
}
}
}
The problem is it will still write the line even if the data is exactly the same elsewhere. I don't want duplicate lines.
Any advice?
Edit
The CertainData is a reference number.
I have a bunch of files that have data in them and the piece I want to seperate and put into a text file is CertainData field, which will have a reference number.
Sometimes the files I get sent will have the same formatted information inside it with the CertainData appearing in them for reference.
When i run this programme, if the text file i have already contains the "CertainData" reference number inside it, i dont want it to be written
If you need anymore clarification let me know and i will update the post
Try with this LINQ:
var previousLines = new HashSet<string>();
File.WriteAllLines(destPath, File.ReadLines(sourcePath)
.Where(line => previousLines.Add(line)));
EDITED :
public void output(string folder)
{
string S = "Data" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xml";
//Trades.Save(S);
string path = Path.Combine(folder, S);
Console.WriteLine(path);
XDocument f = new XDocument(Trades);
f.Save(path);
string[] lines = File.ReadAllLines(path);
File.WriteAllLines(path, lines);
bool isExist = false;
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"H:\Test" + DateTime.Now.ToString("yyMMdd") + ".txt", true))
{
foreach (string line in lines)
{
if (line.Contains("CertainData"))
{
isExist = true;
}
}
if (!isExist)
{
File.AppendAllText(path, "CertainData" + Environment.NewLine);
}
}
}

Parsing CSV data

I am trying to parse a CSV file with data with no luck, i have tried a bunch of tools online and none has been able to parse the CSV file correctly. I am baffled by the fact that i am in here asking for help as one would think parsing CSV data would be something super easy.
The format of the CSV data is like this:
",95,54070,3635,""Test Reservation"",0,102,0.00,0.00,2014-12-31,""Name of customer"",""$12.34 + $10, special price"",""extra information"",,CustomerName,,,,,1234567890,youremail#domain.com,CustomerName,2014-12-31,23:59:59,16,0,60,2,120,0,NULL,NULL,NULL,"
Current code:
private void btnOpenFileDialog_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
string line;
while ((line = reader.ReadLine()) != null)
{
ParseCsvLine(line);
}
}
}
}
private void ParseCsvLine(string line)
{
if (line != string.Empty)
{
string[] result;
using (var csvParser = new TextFieldParser(new StringReader(line)))
{
csvParser.Delimiters = new string[] { "," };
result = csvParser.ReadFields();
}
foreach (var item in result)
{
Console.WriteLine(item + Environment.NewLine);
}
}
}
The result variable only has one item and its:
,95,54070,3635,"Test Reservation",0,102,0.00,0.00,2014-12-31,"Name of customer","$12.34 + $10, special price","extra information",,CustomerName,,,,,1234567890,youremail#domain.com,CustomerName,2014-12-31,23:59:59,16,0,60,2,120,0,NULL,NULL,NULL,
// Add Microsoft.VisualBasic.dll to References.
using Microsoft.VisualBasic.FileIO;
// input is your original line from csv.
// Remove starting and ending quotes.
input = input.Remove(0, 1);
input = input.Remove(input.Length - 1);
// Replace double quotes with single quotes.
input = input.Replace("\"\"", "\"");
string[] result;
using (var csvParser = new TextFieldParser(new StringReader(input)))
{
csvParser.Delimiters = new string[] { "," };
result = csvParser.ReadFields();
}
You can check out a previous post that deals with those pesky commas in csv files. I'm linking it here.
Also Mihai, your solution works well for just the one line but will fail once there are many lines to parse.

Writing a specific line from one text file to other text file using c#

I Am using sharp develop. I am making a Win App using C# . I want my program check a text file named test in drive c: and find the line which contains "=" and then write this line to other newly created text file in drive c: .
Try this one-liner:
File.WriteAllLines(destinationFileName,
File.ReadAllLines(sourceFileName)
.Where(x => x.Contains("=")));
Here's another simple way using File.ReadLines, Linq's Where and File.AppendAllLines
var path1 = #"C:\test.txt";
var path2 = #"C:\test_out.txt";
var equalLines = File.ReadLines(path1)
.Where(l => l.Contains("="));
File.AppendAllLines(path2, equalLines.Take(1));
using(StreamWriter sw = new StreamWriter(#"C:\destinationFile.txt"))
{
StreamReader sr = new StreamReader(#"C:\sourceFile.txt");
string line = String.Empty;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("=")) { sw.WriteLine(line)); }
}
sr.Close();
}
Have you tried something?
Here are two ways to read a file:
Use static methods available in File class. ReadAllLines to be specific. This is good enough if you are dealing with small files. Next, once you have the array, just find the item with "=" using LINQ or by any other iteration method. Once you got the line, again use File class to create and write data to the file.
If you are dealing with large files, use Stream. Rest remains fairly same.
if (File.Exists(txtBaseAddress.Text))
{
StreamReader sr = new StreamReader(txtBaseAddress.Text);
string line;
string fileText = "";
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("="))
{
fileText += line;
}
}
sr.Close();
if (fileText != "")
{
try
{
StreamWriter sw = new StreamWriter(txtDestAddress.Text);
sw.Write(fileText);
sw.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
a bit edited Furqan's answer
using (StreamReader sr = new StreamReader(#"C:\Users\Username\Documents\a.txt"))
using (StreamWriter sw = new StreamWriter(#"C:\Users\Username\Documents\b.txt"))
{
int counter = 0;
string line = String.Empty;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("="))
{
sw.WriteLine(line);
if (++counter == 4)
{
sw.WriteLine();
counter = 0;
}
}
}
}

Categories

Resources