简体   繁体   English

如何在文本文件中逐行读取和替换字符串?

[英]How can I read and replace Strings line by line in a Text File?

I have a text file that reads this: 我有一个文本文件,读取:

INSERT INTO `shops` VALUES ('', '3', '1000000', '0');
INSERT INTO `shops` VALUES ('', '3', '1000010', '0');
INSERT INTO `shops` VALUES ('', '3', '1000020', '0');
INSERT INTO `shops` VALUES ('', '3', '1000030', '0');
INSERT INTO `shops` VALUES ('', '3', '1001000', '0');

Notice for each line the first key is ''. 请注意每行第一个键是''。 For each line, I want to find that '', and replace it with a number (starting with 1), then add 1 to it as it goes to the next line, Like so: 对于每一行,我想找到'',并用数字(从1开始)替换它,然后在它进入下一行时加1,如下所示:

INSERT INTO `shops` VALUES ('1', '3', '1000000', '0');
INSERT INTO `shops` VALUES ('2', '3', '1000010', '0');
INSERT INTO `shops` VALUES ('3', '3', '1000020', '0');
INSERT INTO `shops` VALUES ('4', '3', '1000030', '0');
INSERT INTO `shops` VALUES ('5', '3', '1001000', '0');

I've been trying to do this for a couple of hours but I'm failing. 我一直试图这样做几个小时,但我失败了。

Here is what I've been thinking of (I know this is far from right, but I'm not that savvy in c#, so maybe one of you can help me come up with the right code): 这就是我一直在想的(我知道这远非正确,但我在c#中并不精通,所以也许你们中的一个可以帮我提出正确的代码):

string text = File.ReadAllText("C:\\Users\\Donavon\\Desktop\\old.sql");

int i = 0;
text = text.Replace("('',", "('" + i + "',");
i++;
File.WriteAllText("C:\\Users\\Donavon\\Desktop\\new.sql", text);

Thanks for any help, It's greatly appreciated 感谢您的帮助,非常感谢

You will want to do something along these lines: 你会想要沿着这些方向做点什么:

var lineNumber = 0;

using (var newFile = File.AppendText(@"c:\temp\new.sql"))
{
    foreach (var line in File.ReadLines(@"c:\temp\old.sql"))
    {
        lineNumber++;

        var updatedLine = line.Replace("('',", "('" + lineNumber.ToString() + "',");

        newFile.WriteLine(updatedLine);
    }
}

Use File.ReadLines to enumerate the lines so you don't get memory exceptions with big files 使用File.ReadLines枚举行 ,这样就不会获得大文件的内存异常

You can read the lines in individually: 您可以单独阅读这些行:

string text = "";
using (StreamReader sr = new StreamReader("C:\\Users\\Donavon\\Desktop\\old.sql"))
{
    int i = 0;
    do
    {
        i++;
        string line = sr.ReadLine();
        if (line != "")
        {
            line = line.Replace("('',", "('" + i + "',");
            text = text + line + Environment.NewLine;
        }
    } while (sr.EndOfStream == false);
}
File.WriteAllText("C:\\Users\\Donavon\\Desktop\\new.sql", text);

Not a code solution here, but if I had to do such thing and I knew the position of the character would always be the same (like your example), I would opt to use Notepad++ for a quick edit and don't bother learning programming languages. 这里不是代码解决方案,但如果我必须做这样的事情并且我知道角色的位置总是相同的(就像你的例子),我会选择使用Notepad ++进行快速编辑而不打扰学习编程语言。

  1. Place the cursor in between '' and use the shortcut ALT+C 将光标放在''之间,然后使用快捷键ALT + C.

  2. Select the option "Number to Insert", fill initial number (1) and increase by (1) 选择“要插入的数字”选项,填写初始编号(1)并增加(1)

   var lines = File.ReadAllLines(@"D:\temp\old.sql");

    for (int i = 0; i < lines.Count(); ++i)
         lines[i] = lines[i].Replace("\'\'", string.Format("\'{0}\'", i + 1));

    File.WriteAllLines(@"D:\temp\new.sql", lines);

I think this will work. 我认为这会奏效。 Got most of it from MSDN . MSDN获得大部分内容。

  int counter = 1;
        string line;

        // Read the file and display it line by line.
        System.IO.StreamReader file = 
           new System.IO.StreamReader("C:\\Users\\Donavon\\Desktop\\old.sql");

        while((line = file.ReadLine()) != null)
        {
           line.Replace("('',", "('" + counter.ToString() + "',");;
           counter++;
        }

string text = File.ReadAllText("C:\\Users\\person\\Desktop\\old.sql"); string text = File.ReadAllText(“C:\\ Users \\ person \\ Desktop \\ old.sql”); System.Text.StringBuilder strBuilder = new StringBuilder(); System.Text.StringBuilder strBuilder = new StringBuilder();

        int i = 0;

        var theSplotStr = text.Split('\n');

        foreach (var item in theSplotStr)
        {
            System.Console.WriteLine(item);
            string revisedString = item.Replace("''", "'" + ++i + "'");
            strBuilder.Append(revisedString+"\n");

        }

        File.WriteAllText("C:\\Users\\person\\Desktop\\new.sql", strBuilder.ToString());

Here is a hammer for you to push your thumb-pin in the board... 这是一把锤子,可以将拇指针推到板子上......

If you are interested, you can perform this operation faster by doing it in parallel. 如果您感兴趣,可以通过并行执行此操作。 Start one task to read the lines from old file, multiple processor tasks to sanitize the lines read by reader task, and one writer task to write the results back to disk. 启动一个任务以读取旧文件中的行,多个处理器任务以清理读取器任务读取的行,以及一个写入任务以将结果写回磁盘。

On my 8-core machine I am able to process a 124MB file, using ~100% CPU, in less than 3 seconds. 在我的8核机器上,我能够在不到3秒的时间内使用~100%CPU处理124MB文件。

Attached below is a fully commented code. 下面附有完整注释的代码。

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public static class Test
    {
        //The paths to read and write
        const string OldFilePath = @"C:\Users\Donavon\Desktop\old.sql";
        const string NewFilePath = @"C:\Users\Donavon\Desktop\new.sql";

        //The maximum number of lines we can read for parallel processing
        //given the memory restrictions etc. Please set this to a number 
        //that is optimum for you.
        static readonly int ExpectedMaxLines = (int)Math.Pow(2, 10);

        //The data structures to hold the old and new lines
        private static readonly BlockingCollection<string> DirtyLines = new BlockingCollection<string>(ExpectedMaxLines);
        private static readonly BlockingCollection<string> CleanLines = new BlockingCollection<string>(ExpectedMaxLines);

        //A common factory. Since all tasks are long running, this is enough.
        private static readonly TaskFactory TaskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);

        public static void Main()
        {
            //Need to start one reader task which will read one line at a time and
            //put that line in the BlockingCollection for parallel processing.

            BeginReader();

            BeginParallelProcessing();

            //We have started 1 reader task and multiple processor tasks
            //Now we need to start a writer task that will write the cleaned lines to disk
            var finalTask = BeginWriter();

            //Since writer task is the task which will signify the end of the entire 
            //exercise of reading, processing and writing, we will wait till the 
            //writer task has finished too.
            Task.WaitAll(new[] {finalTask});

            Console.WriteLine("All text lines cleaned and written to disk.");
        }

        private static void BeginReader()
        {
            TaskFactory.StartNew(() =>
            {
                Console.WriteLine("Reader task initiated.");
                using (var reader = new StreamReader(OldFilePath))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        DirtyLines.TryAdd(line);
                    }
                    DirtyLines.CompleteAdding();
                }
            });
        }

        private static void BeginParallelProcessing()
        {
            //Starting as many processor tasks as there are number of processors available
            //on this machine. These tasks will return when there are no more lines to process

            //Globally defined id, and a lock, for adding in the required lines.
            var globalId = 1;
            var idLock = new object();

            for (var taskIndex = 0; taskIndex < Environment.ProcessorCount; taskIndex++)
            {
                TaskFactory.StartNew(() =>
                {
                    while (!DirtyLines.IsCompleted)
                    {
                        string line, updatedLine;
                        if (!DirtyLines.TryTake(out line)) continue;
                        if (line.Contains("(''"))
                        {
                            int nextGlobalId;
                            lock (idLock)
                            {
                                nextGlobalId = globalId++;
                            }
                            updatedLine = line.Replace("('',", "('" + nextGlobalId + "',");
                        }
                        else
                        {
                            updatedLine = line;
                        }
                        CleanLines.Add(updatedLine);
                    }
                    //Adding a delay of 10 seconds to allow all processing tasks to finish
                    Task.Delay(10*1000);
                    if (!CleanLines.IsAddingCompleted)
                    {
                        CleanLines.CompleteAdding();
                    }
                });
            }
        }

        private static Task BeginWriter()
        {
            var finalTask = TaskFactory.StartNew(() =>
            {
                Console.WriteLine("Writer task initiated.");
                using (var writer = new StreamWriter(NewFilePath))
                {
                    while (!CleanLines.IsCompleted)
                    {
                        string cleanLine;
                        if (!CleanLines.TryTake(out cleanLine)) continue;
                        writer.WriteLine(cleanLine);
                    }
                }
            });
            return finalTask;
        }
    }
}
// Read file in by line (give us an array to work with)
var file = File.ReadAllLines("old.sql");

// Write the lines back (after we've modified it through LINQ)
File.WriteAllLines("new.sql", file.Select((line,index) => {
  // Use the overload of `.Select()` which includes the index

  // Simple string replace at this point, inserting our index.
  return line.Replace("('',", String.Format("('{0}',", index));
}));
string text = File.ReadAllText("old.sql");
text = text.Replace("some text", "new value");
File.WriteAllText("old.sql", text);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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