I'm trying to update specific lines in text file using this condition:
if line contain Word-to-search remove only the next space
using the blew code :
using (System.IO.TextReader tr = File.OpenText((#"d:\\My File3.log")))
{
string line;
while ((line = tr.ReadLine()) != null)
{
string[] items = line.Trim().Split(' ');
foreach (var s in items)
{
if (s == "a" || s == "b")
s = s.Replace(" ", "");
using (StreamWriter tw = new StreamWriter(#"d:\\My File3.log"))
tw.WriteLine(s);
my file is llike :
k l m
x y z a c
b d a w
the update file shold be like :
k l m
x y z ac
bd aw
I think you can do it by:
...
if (s == "a" || s == "b"){
if (s == "a")
s = s.Replace("a ", "a");
if (s == "b")
s = s.Replace("b ", "b");
using (StreamWriter tw = new StreamWriter(#"d:\\My File3.log"))
tw.WriteLine(s);
}
...
SAMPLE:
string test="a c";
test =test.Replace("a ", "a");
Console.WriteLine(test);
OUTPUT:
ac
try this:
....
while ((line = tr.ReadLine()) != null)
{
using (StreamWriter tw = new StreamWriter(#"d:\\My File3.log"))
string st = line.Replace("a ", "a").Replace("b ", "b");//just add additional .Replace() here
tw.WriteLine(st);
}
Your problem, I think, is here:
if (s == "a" || s == "b")
s = s.Replace(" ", "");
In order to satisfy your if condition, string s is necessarily without any spaces in it. Your code, therefore, does nothing.
if(s == "a" || s == "b")
foreach(var s2 in items)
{
if(items.IndexOf(s2) > items.IndexOf(s) && s2 == " ")
s2 == string.Empty;
break;
}
The break exists to ensure we only replace the next space, not all spaces following the character.
Are you looking for String.Replace?
string path = #"d:\My File3.log";
var data = File
.ReadLines(path)
.Select(line => line
.Replace("a ", "a")
.Replace("b ", "b"))
.ToList(); // Materialization, since we have to write back to the same file
File.WriteAllLines(path, data);
In general case, e.g.
if line contain Word-to-search
means that a and b should be words (b within abc is not the word we are looking for):
"abc a b c a" -> "abc abc a"
try using regular expressions:
string[] words = new string[] { "a", "b" };
string pattern =
#"\b(" + string.Join("|",
words.Select(item => Regex.Escape(item))) +
#")\s";
var data = File
.ReadLines(path)
.Select(line => Regex.Replace(line, pattern, m => m.Groups[1].Value))
.ToList();
File.WriteAllLines(path, data);
you should consider a temporary variable just before foreach loop
int temp = 0;
foreach(var s in items)
{
if (temp == 0)
{
if (s == "a" || s == "b")
{
temp = 1;
}
}
else
{
s = s.Replace(" ", "");
using (StreamWriter tw = new StreamWriter(#"d:\\My File3.log"))
tw.WriteLine(s);
temp = 0;
}
}
You cannot read and write at the same iteration to the same file.
Here a solution using StringBuilder (with him you can manipulate chars in the string):
using (StreamWriter tw = new StreamWriter(#"file1.txt"))
{
using (System.IO.TextReader tr = File.OpenText((#"file.txt")))
{
string line;
StringBuilder items = new StringBuilder();
while ((line = tr.ReadLine()) != null)
{
items.Append(line);
items.Replace("a ", "a");
items.Replace("b ", "b");
tw.WriteLine(items);
items.Clear();
}
}
}
Related
how can i read from a text file , from a specific location for example i have a textfile
pathA = sometexthere$
pathB = sometexthere$
pathC = sometexthere$
TimerTC = sometexthere$
I want to read everything between "=" and "$"
To read line by line i'm using this:
int counter = 0;
string line;
System.IO.StreamReader file = new System.IO.StreamReader("config.cfg");
while((line = file.ReadLine()) != null)
{
if (counter == 1)
{
label1.Text=line;
counter++;
}
else if (counter == 2)
{
label2.Text=line;
counter++;
}
}
You can use SkipWhile and TakeWhile methods:
File.ReadLines("path")
.Select(line => new string(line
.SkipWhile(c => c != '=')
.Skip(1)
.TakeWhile(c => c != '$').ToArray())).ToList();
Solution 1:
int index;
List<string> listLines = new List<string>();
foreach (var line in File.ReadLines("C:\\Data.txt"))
{
index = line.LastIndexOf('=');
listLines.Add(line.Substring(index + 1, (line.Length - index) -
((line.Length) - line.LastIndexOf('$')+1)));
}
Solution2:
you can split every line with delimter = and then extract the word starting with = ending with $
string str;
List<string> listLines = new List<string>();
foreach (var line in File.ReadLines("C:\\Data.txt"))
{
str = line.Split('=')[1].Trim();
listLines.Add(str.Substring(0, str.Length -
(str.Length - str.LastIndexOf('$'))));
}
Solution 3:
List<string> listLines = new List<string>();
foreach (var line in File.ReadLines("C:\\Data.txt"))
{
var str = line.Split(new char[] { '=', '$'},
StringSplitOptions.RemoveEmptyEntries);
listLines.Add(str[1].Trim());
}
You can also do it using a Regex (although, now you have two problems):
var regex = new Regex(
#"^ # beginning of the line
(?<key>.*?) # part before the equals sign
\s*=\s* # `=` with optional whitespace
(?<value>.*) # part after the equals sign
\$ # `$`
$ # end of the line",
RegexOptions.Multiline |
RegexOptions.IgnorePatternWhitespace |
RegexOptions.Compiled);
Or, a one liner:
var regex = new Regex(#"^(?<key>.*?)\s*=\s*(?<value>.*)\$$");
And then select matches into key-value pairs:
var keyValuePairs = File
.ReadLines("config.cfg")
.Select(line => regex.Match(line))
.Where(match => match.Success)
.Select(match => new
{
Key = match.Groups["key"].Value,
Value = match.Groups["value"].Value
})
.ToList();
I need to read a list of names from a text file nameInput.txt, the names are formatted as first_name,last_name, one pair per line.
For example:
David,Smith
Russell,Jones
Andrew,Jones
Then I need to arrange it in alphabetical order by with primary key last name, secondary key first name, for example:
Jones Andrew
Jones Russell
Smith David
Last, I need to write the sorted data to another file nameOutput.txt, the names are written as one pair per row in last_name first_name order, for example:
Jones Andrew
Jones Russell
Smith David
This is my code currently:
class MainClass
{
public static void Main (string[] args)
{
List<string> list = new List<string> ();
using (StreamReader reader = new StreamReader("Documents/inputName.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
list.Add (line);
Console.WriteLine (line);
}
}
}
}
If you are allowed to use LINQ methods, here is an example about how to do it:
var lines = File.ReadLines("inputFilePath")
.Select(x => x.Split(',').Reverse().ToArray())
.OrderBy(x => x[0])
.ThenBy(x => x[1])
.Select(x => string.Join(" ", x));
File.WriteAllLines("outputFilePath", lines);
UPDATE: Here is a non-linq solution with your code:
Create a custom comparer:
public class NameComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null || y == null) return -1;
var parts1 = x.Split();
var parts2 = y.Split();
if (parts1.Length > 1 && parts2.Length > 1)
{
if (parts1[0] != parts2[0]) return parts1[0].CompareTo(parts2[0]);
return parts1[1].CompareTo(parts2[1]);
}
return x.CompareTo(y);
}
}
And use it to sort your names:
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader("Documents/inputName.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var parts = line.Split(',');
Array.Reverse(parts);
list.Add(string.Join(" ", parts));
}
}
list.Sort(new NameComparer());
using (StreamWriter writer = new StreamWriter("outputfile.txt"))
{
foreach(var line in list)
writer.WriteLine(line);
}
is it possible to transform an expression like
{op1 == op2, #} && {op3 > op4, 1, 2} && op5 == op6
to
op1 ==_# op2 && op3 >_1_2 op4 && op5 == op6
So, all occurences after the comma should be placed seperated by an underline after the operator (==, >,<,<=, etc...). opX can be any alphanumerical value.
After Qtax's comment, I just wrote a solution:
var st = "{op1 == op2, #} && {op3 > op4, 1, 2} && op5 == op6";
var regex = "{.*?}";
for (var match = Regex.Match(st, regex); match.Success; match = Regex.Match(st, regex))
{
var oldString = match.Value; // {op1 == op2, #}
var op = oldString.Split(' ').ToList()[1].Trim(); // ==
var csv = oldString.Split(',').Select(x => x.Trim()).ToList(); // [0] = "{op1 == op2" [1] = "#}"
var expression = csv[0].Remove(0,1); // op1 == op2
csv.RemoveAt(0);
var extension = "_" + String.Join("_", csv);
extension = extension.Remove(extension.Length-1); // _#
var newString = expression.Replace(op, op + extension);
st = st.Replace(oldString, newString);
}
How can I convert á to a in C#?
For instance: aéíúö => aeiuo
Um, having read those threads [I didn't know they were called diatrics, so I couldn't possible search for that].
I want to "drop" all diatrics but ñ
Currently I have:
public static string RemoveDiacritics(this string text)
{
string normalized = text.Normalize(NormalizationForm.FormD);
var sb = new StringBuilder();
foreach (char c in from c in normalized
let u = CharUnicodeInfo.GetUnicodeCategory(c)
where u != UnicodeCategory.NonSpacingMark
select c)
{
sb.Append(c);
}
return sb.ToString().Normalize(NormalizationForm.FormC);
}
What would be the best way to leave ñ out of this?
My solution was to do the following after the foreach:
var result = sb.ToString();
if (text.Length != result.Length)
throw new ArgumentOutOfRangeException();
int position = -1;
while ((position = text.IndexOf('ñ', position + 1)) > 0)
{
result = result.Remove(position, 1).Insert(position, "ñ");
}
return sb.ToString();
But I'd assume there is a less "manual" way to do this?
if you don´t want remove the ñ, this is a option. It´s fast.
static string[] pats3 = { "é", "É", "á", "Á", "í", "Í", "ó", "Ó", "ú", "Ú" };
static string[] repl3 = { "e", "E", "a", "A", "i", "I", "o", "O", "u", "U" };
static Dictionary<string, string> _var = null;
static Dictionary<string, string> dict
{
get
{
if (_var == null)
{
_var = pats3.Zip(repl3, (k, v) => new { Key = k, Value = v }).ToDictionary(o => o.Key, o => o.Value);
}
return _var;
}
}
private static string RemoveAccent(string text)
{
// using Zip as a shortcut, otherwise setup dictionary differently as others have shown
//var dict = pats3.Zip(repl3, (k, v) => new { Key = k, Value = v }).ToDictionary(o => o.Key, o => o.Value);
//string input = "åÅæÆäÄöÖøØèÈàÀìÌõÕïÏ";
string pattern = String.Join("|", dict.Keys.Select(k => k)); // use ToArray() for .NET 3.5
string result = Regex.Replace(text, pattern, m => dict[m.Value]);
//Console.WriteLine("Pattern: " + pattern);
//Console.WriteLine("Input: " + text);
//Console.WriteLine("Result: " + result);
return result;
}
If you want remove the ñ, the faster option is:
Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(text));
Hey everybody, this is what I have going on. I have two text files. Umm lets call one A.txt and B.txt.
A.txt is a config file that contains a bunch of folder names, only 1 listing per folder.
B.txt is a directory listing that contains folders names and sizes. But B contains a bunch of listing not just 1 entry.
What I need is if B, contains A. Take all lines in B that contain A and write it out as A|B|B|B ect....
So example:
A.txt:
Apple
Orange
Pear
XBSj
HEROE
B.txt:
Apple|3123123
Apple|3434
Orange|99999999
Orange|1234544
Pear|11
Pear|12
XBSJ|43949
XBSJ|43933
Result.txt:
Apple|3123123|3434
Orange|99999999|1234544
Pear|11|12
XBSJ|43949|43933
This is what I had but it's not really doing what I needed.
string[] combineconfig = File.ReadAllLines(#"C:\a.txt");
foreach (string ccline in combineconfig)
{
string[] readlines = File.ReadAllLines(#"C:\b.txt");
if (readlines.Contains(ccline))
{
foreach (string rdlines in readlines)
{
string[] pslines = rdlines.Split('|');
File.AppendAllText(#"C:\result.txt", ccline + '|' + pslines[0]);
}
}
I know realize it's not going to find the first "if" because it reads the entire line and cant find it. But i still believe my output file will not contain what I need.
Assuming you're using .NET 3.5 (so can use LINQ), try this:
string[] configLines = File.ReadAllLines("a.txt");
var dataLines = from line in File.ReadAllLines("b.txt")
let split = line.Split('|')
select new { Key = split[0], Value = split[1] };
var lookup = dataLines.ToLookup(x => x.Key, x => x.Value);
using (TextWriter writer = File.CreateText("result.txt"))
{
foreach (string key in configLines)
{
string[] values = lookup[key].ToArray();
if (values.Length > 0)
{
writer.WriteLine("{0}|{1}", key, string.Join("|", values));
}
}
}
var a = new HashSet<string>(File.ReadAllLines(#"a.txt")
.SelectMany(line => line.Split(' ')),
StringComparer.CurrentCultureIgnoreCase);
var c = File.ReadAllLines(#"b.txt")
.Select(line => line.Split('|'))
.GroupBy(item => item[0], item => item[1])
.Where(group => a.Contains(group.Key))
.Select(group => group.Key + "|" + string.Join("|", group.ToArray()))
.ToArray();
File.WriteAllLines("result.txt", c);
Output:
Apple|3123123|3434
Orange|99999999|1234544
Pear|11|12
XBSJ|43949|43933
A short one :
var a = File.ReadAllLines("A.txt");
var b = File.ReadAllLines("B.txt");
var query =
from bline in b
let parts = bline.Split('|')
group parts[1] by parts[0] into bg
join aline in a on bg.Key equals aline
select aline + "|" + string.Join("|", bg.ToArray());
File.WriteAllLines("result.txt", query.ToArray());
This should work:
using System;
using System.Linq;
using System.IO;
using System.Globalization;
namespace SO2593168
{
class Program
{
static void Main(string[] args)
{
var a = File.ReadAllLines("A.txt");
var b =
(from line in File.ReadAllLines("B.txt")
let parts = line.Split('|')
select new { key = parts[0], value = parts[1] });
var comparer = StringComparer.Create(CultureInfo.InvariantCulture, true);
var result =
from key in a
from keyvalue in b
where comparer.Compare(keyvalue.key, key) == 0
group keyvalue.value by keyvalue.key into g
select new { g.Key, values = String.Join("|", g.ToArray()) };
foreach (var entry in result)
Console.Out.WriteLine(entry.Key + "|" + entry.values);
}
}
}
This produces:
Apple|3123123|3434
Orange|99999999|1234544
Pear|11|12
XBSJ|43949|43933
Code here.