2

我拥有text1.txt并拥有以下内容:

longitude,latt,u,70772,xxxx
31, 121, -10.2
31, 122, -20.9
31, 123, 40.8
.
.
44, 131, -44.1

我拥有text2.txt并拥有以下内容:

longitude,latt,v,70772,xxxx
31, 121, 12.1
31, 122, 32.4
31, 123, -2.5
.
.
44, 131, 7.3

正如你所看到的,text1.txt并且text2.txt有一些相同的共性。

第一个常见:每个文本文件的第一行应该被跳过,因为包含不重要的信息

2nd common:每个文本文件包含相同的经度和纬度值,即

31 , 121 , x
31 , 122 , x
31 , 123 , x
.
.
44 , 131 , x

我的目标是合并并text1.txt得到以下结果:text2.txtresult.txt

31, 121, -10.2, 12.1
31, 121, -20.9, 32.4
31, 123, 40.8, -2.5
.
.
44, 131, -44.1, 7.3

参考这个源MergeTwoTextFile我已经知道如何合并两个文本文件。但我不知道的是,如何合并具有某些特定条件的两个文本文件。

我希望可以做一些类似的事情concatdistict有什么想法吗?

更新: 3 个 UI 按钮

在此处输入图像描述

打开文件按钮的代码

private void toolStripBtnOpenV_Click(object sender, EventArgs e)
{
        toolStripBtnOpenV.Enabled = false;

        openFileDialog1.FileName = "";

        openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";

        if (openFileDialog1.ShowDialog() != DialogResult.OK)
            return;

        v_filePath = openFileDialog1.FileName;

        if (toolStripBtnOpenU.Enabled == false)
        {
            toolStripBtnMerge.Enabled = true;
        }
}

在 MergeUV button_click 事件中,按照 SamiHuutoniemi 的建议进行操作,除了像这样更改第一行:

List<string> filelist = new List<string>() { v_filePath , u_filePath };

如果您的文件大小 > 5MB,则写入输出文件至少需要 20 分钟

4

3 回答 3

2

您可以读取两个文本文件,将数据保存为列表Tuple<int, int, List<double>>(在这种情况下,您的元组是“唯一的”,即没有两个元组共享两个整数)。然后输出一个文本文件,以您的格式打印所有元组。

这完成了我认为你想做的事情。

List<string> filelist = new List<string>() { "text1.txt", "text2.txt" };
List<Tuple<int, int, List<double>>> dataList = new List<Tuple<int, int, List<double>>>();

foreach (var file in filelist)
{
    string line;
    using (TextReader tr = new StreamReader(file))
    {
        tr.ReadLine();  //skip header
        while ((line = tr.ReadLine()) != null)
        {
            var tokens = line.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            int longitude = int.Parse(tokens[0]);
            int latitude = int.Parse(tokens[1]);
            double value = double.Parse(tokens[2], CultureInfo.InvariantCulture);

            Tuple<int, int, List<double>> t = dataList.Where(x => (int)x.Item1 == longitude && (int)x.Item2 == latitude).FirstOrDefault();
            if (t == null)
            {
                dataList.Add(new Tuple<int, int, List<double>>(longitude, latitude, new List<double>() { value }));
            }
            else
            {
                t.Item3.Add(value);
            }
        }
    }
}

using (TextWriter tw = new StreamWriter("output.txt"))
{
    foreach (var t in dataList)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(String.Format("{0}, {1}, ", t.Item1, t.Item2));
        foreach (var value in t.Item3)
        {
            sb.Append(String.Format("{0}, ", value));
        }

        tw.WriteLine(sb.ToString());
    }
}
于 2013-06-05T15:44:38.633 回答
2

像这样的东西?

var file1 = File.ReadAllLines("path1");
var file2 = File.ReadAllLines("path2");

var result = new List<string>();

//Skip line 0
for (int i = 1; i < file1.Length; i++)
{
    //Get the values from each correseponding file
    var file1Values  = file1[i].Split(',').Select(v => v.Trim());
    var file2Values  = file2[i].Split(',').Select(v => v.Trim());

    //Get distinct values & join
    result.Add(string.Join(",", file1Values.Union(file2Values)));
}

File.WriteAllLines("resultpath", result);
于 2013-06-05T15:47:55.073 回答
0

要在没有第一行的情况下合并它们,你可以试试这个单行:

File.WriteAllLines("result.txt", File.ReadLines("text1.txt").Skip(1).Concat(File.ReadLines("text2.txt").Skip(1)));

如果您需要在纯逐行比较级别上区分它们:

File.WriteAllLines("result.txt", File.ReadLines("text1.txt").Skip(1).Concat(File.ReadLines("text2.txt").Skip(1)).Distinct());
于 2013-06-05T15:47:47.580 回答