-6

我在一个文件夹中有许多文本文件(1800 个文件),所有这些文件都具有相同的格式。他们是这样开始的:

“站 ABDEHGAH_ 纬度 = 30 27 长 = 51 2

1998 1 35050

1998 2 27800

1998 3 39500

1998 4 0"

我想编辑所有这些的第一行,使其像这样:“ABDEHGAH 30.27 51.2”

我应该怎么办?

4

3 回答 3

2

您将不得不 在所有文件中搜索和_Lat =替换""并替换Long =为。""它将涉及三个步骤:

  1. 您将不得不遍历文件夹中的所有文件。使用 http://msdn.microsoft.com/en-us/library/bb513869.aspx

  2. 读取每个文件的内容。使用http://msdn.microsoft.com/en-us/library/vstudio/ezwyzy7b.aspx

  3. 对于每个文件,查找_Lat =并将Long = 其替换为"". 使用String.Replace方法。请注意,您String.Replace只能在所有文件中一致_Lat =时使用。Long =我的意思是,如果在其中一个文件中它是Station ABDEHGAH_ Lat = 30 27 Long = 51 2,而在另一个文件中则类似于Station ABDEHGAH_ Lat = 30 27 Long=51 2. 注意空间。如果不一致,您将不得不使用RegEx.Replace来查找模式并替换它们。

于 2013-06-23T06:31:33.827 回答
2

此代码有效,请尝试:

string[] files = Directory.GetFiles(@"C:\Users\User\Desktop\AnyFolder");   // You should include System.IO;

foreach (string s in files)
{
    string text = File.ReadAllText(s);
    text = text.Replace("old text", "new text");
    StreamWriter writer = new StreamWriter(s);
    writer.Write(text);
}

如果此代码将帮助您投票给我。

于 2013-06-23T06:55:07.740 回答
1

这种方法的完整来源在这里(Github)

我创建了两个字符串来保存测试的路径

private readonly string sourceFiles = @"temp\source";
private readonly string outputFiles = @"temp\output";

我创建了一个编译的 正则表达式。该表达式将:

  • 忽略第一个字
  • 捕获一个单词(仅限 AZ)并将忽略其他字符,例如_
  • 捕获一个数字Lat =,如果存在另一个数字,则以空格分隔
  • 捕获一个数字Long =,如果存在另一个数字,则以空格分隔

正则表达式:

private readonly Regex firstLineParser =
    new Regex(@"^[^ ]+ (?<StationName>[a-z]+).* Lat = (?<Lat>\d+(\s\d+)?) Long = (?<Long>\d+(\s\d+)?)$"
        , RegexOptions.Compiled | RegexOptions.IgnoreCase
    );

这意味着我将有 3 个组,我可以访问它们来操纵值。

所以,为了测试我使用秒表的性能

public void Run()
{
    // performance test
    var timer = new Stopwatch();

    timer.Start();

Parallel.ForEach将使用线程遍历所有元素以并行运行,在对大量文件执行任务时这是一个好主意。

    Parallel.ForEach(Directory.GetFiles(sourceFiles), f =>
    {

现在,对于每个元素(完整文件路径),我们将创建一个StreamReader

        using (var sr = new StreamReader(f))
        {
            // retrieves just the name of the file
            // after a few tests, it seems to be faster
            // than instantiating a FileInfo, not a big deal though
            var outfilename = f.Split('\\').Last();

            // reads the first line from the source file
            string line = sr.ReadLine();

            // run the expression to match the values
            // we want to separate
            var match = firstLineParser.Match(line);

            // now that we have the groups, we can format
            // the values the way we want
            line = String.Format("{0} {1} {2}"
                , match.Groups["StationName"].Value
                , match.Groups["Lat"].Value.Replace(" ", ".")
                , match.Groups["Long"].Value.Replace(" ", ".")
            );

下面将创建一个StreamWriter

            using (var sw = new StreamWriter(Path.Combine(outputFiles, outfilename)))
            {
                // we modified the first line, so lets write it
                sw.WriteLine(line);

                // now we just rewrite all remaining lines
                while ((line = sr.ReadLine()) != null)
                    sw.WriteLine(line);

                // and write to disk
                sw.Flush();
            }
        }
    });

最后我们停止计时器并显示经过的时间。

    timer.Stop();

    Console.WriteLine(timer.Elapsed.ToString(@"mm\:ss\.fff"));
}
于 2013-06-23T18:08:03.940 回答