DerCha
DerCha

Reputation: 77

C# in extracting text file require information and output with statement

Senario, my company are changing to new application system, the below text are generate by the old application i need to extract the information for our external accounting vendor

Name  computer name/IP address  time    profit
Lynn    PC2/192.168.100.45      1604    5000
Kathy   PC3/192.168.100.46      1700    8500
Mike    PC6/192.168.100.49      1650    8400
Luke    PC8/192.168.100.51      1600    11500

with result like

Set account lynn PC2 from 192.168.100.45 1604 5000 to acc0001 
Set account Kathy PC3 from 192.168.100.46 1700 8500 to acc0002
Set account Mike PC6 from 192.168.100.49 1650 8400 to acc0005
Set account Luke PC8 from 192.168.100.51 1600 11500 to acc0007

Can it be done just using C# programing?

Currently this is my initial thoughts of the coding. But i doubt it works as it probably require overload and header.

using System;
using System.IO;

class Test 
{
    public static void Main() 
    {
        try 
        {
            using (StreamReader sr = new StreamReader(@"C:\temp\Test.txt")) 
            {
                string line(name, computer, IP_ADD, time, Profit);

                while ((line = sr.ReadLine()) != null) 
                {
                    Console.WriteLine(line);
                }
            }
        }

        public static void WriteToFile() 
        {
            using (StreamWriter sw = File.CreateText(@"c:\temp\EResult.txt"))
            {
                sw.WriteLine("Please find the below generated table of 1 to 10"); 
                sw.WriteLine("");
                for (int i = 1; i <= 10; i++)
                {
                    for (int j = 1; j <= 10; j++)
                    {
                        sw.WriteLine();
                    }
                    sw.WriteLine("");
                }
                Console.WriteLine("successfully written on file.");
            }
        }

        catch (Exception e) 
        {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }
    }
}

Upvotes: 3

Views: 101

Answers (2)

DevWouter
DevWouter

Reputation: 126

There are a few ways to do this, but when the text has some kind of structure you can simply use a regex to parse the input and then format the result again.

Regexes might look complex but with a little aid of MSDN it can become quite simple. Or if you want it more visual

Regular expression visualization

See the example on Debuggex

Since it is never explain where "acc007" comes from I will leave that up to you.

void Main()
{
    var input = @"Name  computer name/IP address  time    profit
Lynn    PC2/192.168.100.45      1604    5000
Kathy   PC3/192.168.100.46      1700    8500
Mike    PC6/192.168.100.49      1650    8400
Luke    PC8/192.168.100.51      1600    11500";

    var lines = input.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Skip(1);
    foreach (var line in lines)
    {
        // "\w" means any non-whitespace character
        // "+" means one or more of the previous character
        // "\s" means whitespace
        // "[^/]" means all characters except "/"
        // "\d" means any digit 
        // "\." means "." (since a dot in a regex means any character we need to escape it).
        // The (?<group-name> group-content) allows us to use name a group
        //   so we can find the group more easily the next time.
        var regex = @"(?<name>\w+)\s+(?<PC>[^/]+)/(?<IP>[\d\.]+)\s+(?<time>\d+)\s+(?<profit>\d+)";
        var match = System.Text.RegularExpressions.Regex.Match(line, regex);

        var name = match.Groups["name"].Value;
        var pc = match.Groups["pc"].Value;
        var ip = match.Groups["ip"].Value;
        var time = match.Groups["time"].Value;
        var profit = match.Groups["profit"].Value;

        // Set account Luke PC8 from 192.168.100.51 1600 11500 to acc0007
        var result = string.Format("Set account {0} {1} from {2} {3} {4} to {5}", name, pc, ip, time, profit, "acc007");

        // Print the result to screen
        Console.WriteLine(result);
    }   
}

Upvotes: 2

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391416

To do this you should:

  1. Read and interpret the old file using a CSV library
  2. Write out the data to a new file using the new format

One thing you haven't mentioned is how you lookup acc0001, the final part of each new line. You will need to figure this part out.

Here is a sample LINQPad program that demonstrates the steps over, please note that you need to add a nuget package, "CsvHelper", for this program to work:

void Main()
{
    var transactions = ReadTransactionsInOldFormat(@"d:\temp\input.txt");
    WriteTransactionsInNewFormat(transactions, @"d:\temp\output.txt");
}

public static void WriteTransactionsInNewFormat(IEnumerable<Transaction> transactions, string filename)
{
    using (var file = File.CreateText(filename))
        foreach (var transaction in transactions)
            file.WriteLine($"Set account {transaction.Name} {transaction.ComputerName} from {transaction.IpAddress} {transaction.Time} {transaction.Profit} to acc0001");
}

public static IEnumerable<Transaction> ReadTransactionsInOldFormat(string filename)
{
    using (var file = File.OpenText(filename))
    using (var reader = new CsvReader(file))
    {
        reader.Configuration.HasHeaderRecord = true;
        reader.Configuration.Delimiter = "\t";
        reader.Configuration.RegisterClassMap<TransactionMap>();

        while (reader.Read())
            yield return reader.GetRecord<Transaction>();
    }
}

public class TransactionMap : CsvClassMap<Transaction>
{
    public TransactionMap()
    {
        Map(m => m.Name).Index(0);
        Map(m => m.ComputerNameAndIpAddress).Index(1);
        Map(m => m.Time).Index(2);
        Map(m => m.Profit).Index(3);
    }
}

public class Transaction
{
    public string Name { get; set; }


    public string ComputerNameAndIpAddress
    {
        get
        {
            return $"{ComputerName}/{IpAddress}";
        }
        set
        {
            var parts = value.Split('/');
            ComputerName = parts[0];
            IpAddress = parts[1];
        }
    }

    public string ComputerName { get; set; }
    public string IpAddress { get; set; }
    public int Time { get; set; }
    public int Profit { get; set; }
}

Upvotes: 1

Related Questions