简体   繁体   中英

How to read a text file for a specific word in lines and write the entire lines to another text file?

I have a text file (say text1.txt) with the following lines:

4410 Rel testRel1
4411 Dbg testDbg1
4412 Dbg testDbg2
4412 Rel testRel2
4413 Rel testRel3
4413 Dbg testDbg3
4414 Rel testRel4
4415 Rel testRel5

Now, I want to write all the lines with word "Rel" to a text file (say text2.txt). So my text2.txt should look like:

4410 Rel testRel1
4412 Rel testRel2
4413 Rel testRel3
4414 Rel testRel4
4415 Rel testRel5

Atlast, My code should read text2.txt return the first four characters of the last line of text2.txt(ie 4415) taking path of text1.txt as input. Below is my code. May be I may have written half of it and with no idea of c#.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.IO;
using Microsoft.TeamFoundation.Build.Client;

namespace Build_Tasks.Activities
{
    [BuildActivity(HostEnvironmentOption.All)]
    public sealed class GetBuildNumber : CodeActivity
    {
        // Define an activity input argument of type string
        public InArgument<string> TextFileName { get; set; }
        public OutArgument<string> setBuildNumber { get; set; }
        private string temp_FilePath = "c:\\temp.txt";

        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
        protected override void Execute(CodeActivityContext context)
        {
            // Obtain the runtime value of the Text input argument
            string TextFileName = context.GetValue(this.TextFileName);
            string TextFilePath = TextFileName;
            string[] Lines = File.ReadAllLines(TextFilePath);
            //string wordrel = "Rel";
            System.IO.StreamReader file = new System.IO.StreamReader(TextFilePath);
            List<string> Spec = new List<string>();
            string line;
            System.IO.StreamWriter file2 = new System.IO.StreamWriter(temp_FilePath);
            while ((line = file.ReadLine()) != null)
            {
                if(line.Contains("Rel"))
                     {
                        file2.WriteLine(line);
                      }
            }
            var lastline = File.ReadLines(temp_FilePath).Last();
            string number = lastline.Substring(0, 4);
            context.SetValue<string>(this.setBuildNumber, number);
            }
    }
    }

Try this....

    static void Main(string[] args)
    {
        int counter = 0;
        string line;

        // Read the file(your SXA file) and display it line by line.
        System.IO.StreamReader file = new System.IO.StreamReader("c:\\SXA63.txt");
        while((line = file.ReadLine()) != null)
         {         //File to write lines which contain Rel. 
                   using(StreamWriter writer = new StreamWriter("c:\\Relfile.txt",true))
                    {
                       if(line.Contains("Rel"))
                      writer.WriteLine(line);
                    }
            counter++;

        }
        String last = File.ReadLines(@"C:\Relfile.txt").Last();
        string buildNo = last.Substring(0, 4);
        file.Close();
        Console.ReadKey();

    }
}

If all you need file2 for is to get the build number, you don't have to create it at all:

protected override void Execute(CodeActivityContext context)
{
    // Obtain the runtime value of the Text input argument
    string TextFileName = context.GetValue(this.TextFileName);
    string TextFilePath = TextFileName;

    string number = null;
    var splitChars = new[]{ ' ' };

    foreach (var line in File.ReadLines(TextFilePath))
    {
        var values = line.Split(splitChars, StringSplitOptions.RemoveEmptyEntries).ToArray();
        if (values.Length < 3)
            continue;

        buildNumber = (values[1] == "Rel" ? values[0] : buildNumber);
    }

    context.SetValue<string>(this.setBuildNumber, number);        
}

And since you are only interested in the last build number, this can be further optimized by not reading the file from the beginning but seeking the stream to the end and jumping back until you find the line with Rel .

This would iterate through the lines of the original file and copy the relevant lines to the new file:

string tempFile = "text2.txt";
List<string> linesWithREL = new List<string>();
using (var sr = new StreamReader("file.txt"))
using (var sw = new StreamWriter(tempFile))
{
    string line;

    while ((line = sr.ReadLine()) != null)
    {
        //check if the current line should be copied
        if (line.Contains("whatever"))
        {
               linesWithREL.Add(line.Substring(0,4));
               sw.WriteLine(line);
        }
    }
}

Try This:

string path1 = @"C:\data1.txt";
string path2 = @"C:\data2.txt";
string searchKey = "Rel";
List<string> newlines = new List<string>();
foreach (var line in File.ReadLines(path1))
{
if (line.Split(new char[]{' '},
         StringSplitOptions.RemoveEmptyEntries)[1].Contains(searchKey))
{
newlines.Add(line);
}
}
File.WriteAllLines(path2,newlines.ToArray());

OK, so as I read some comments, your problem isn't in read/write, but in this line:

var lastline = File.ReadLines(temp_FilePath).Last();

You have to close your writer first, before using a File.ReadLine on same file.

file2.Flush();
file2.Close();
var lastline = File.ReadLines(temp_FilePath).Last();

If you want to optimize your code, there was a few answers added, no need to duplicate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM