c#从csv中删除行

时间:2011-10-17 15:09:33

标签: c# .net linq csv

我有两个csv文件。在第一个文件中我有一个用户列表,在第二个文件中我有一个重复用户列表。我试图删除第一个文件中与第二个文件相同的行。

这是我到目前为止的代码:

StreamWriter sw = new StreamWriter(path3);
        StreamReader sr = new StreamReader(path2);

        string[] lines = File.ReadAllLines(path);

        foreach (string line in lines)
        {
            string user = sr.ReadLine();

            if (line != user) 
            {
                sw.WriteLine(line);

            }

文件1示例:

Modify,ABAMA3C,Allpay - Free State - HO,09072701

Modify,ABCG327,Processing Centre,09085980

文件2示例:

Modify,ABAA323,Group HR Credit Risk & Finance

Modify,ABAB959,Channel Sales & Service,09071036

有什么建议吗?

感谢。

6 个答案:

答案 0 :(得分:3)

您需要做的就是在下面的代码中更改以下文件路径,然后您将获得一个文件(文件一),而不会从文件2中找到重复的用户。此代码的编写记住了您的想法想要易于理解的东西。当然还有其他更优雅的解决方案,但我想让它尽可能基本适合你:

(将其粘贴到程序的主要方法中)

        string line;
        StreamReader sr = new StreamReader(@"C:\Users\J\Desktop\texts\First.txt");

        StreamReader sr2 = new StreamReader(@"C:\Users\J\Desktop\texts\Second.txt");

        List<String> fileOne = new List<string>();
        List<String> fileTwo = new List<string>();

        while (sr.Peek() >= 0)
        {
            line = sr.ReadLine();
            if(line != "")
            {
                fileOne.Add(line);
            }
        }
        sr.Close();
        while (sr2.Peek() >= 0)
        {
            line = sr2.ReadLine();
            if (line != "")
            {
                fileTwo.Add(line);
            }
        }
        sr2.Close();
        var t = fileOne.Except(fileTwo);

        StreamWriter sw = new StreamWriter(@"C:\Users\justin\Desktop\texts\First.txt");

        foreach(var z in t)
        {
            sw.WriteLine(z);
        }
        sw.Flush();

答案 1 :(得分:2)

如果这不是家庭作业,而是制作品,并且你可以安装组件,如果你吞下自己的骄傲并使用一块VB库,你将节省3个小时的生命:

有许多例外(逗号之间的CR / LF =引号中的合法;不同类型的引号;等等)这将处理excel将导出/导入的任何内容。

从我在其中使用的程序中加载“Person”类的示例代码:

    Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(CSVPath)

        Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
        Reader.Delimiters = New String() {","}
        Reader.TrimWhiteSpace = True
        Reader.HasFieldsEnclosedInQuotes = True

        While Not Reader.EndOfData
            Try
                Dim st2 As New List(Of String)
                st2.addrange(Reader.ReadFields())
                If iCount > 0 Then ' ignore first row = field names
                    Dim p As New Person
                    p.CSVLine = st2
                    p.FirstName = st2(1).Trim
                    If st2.Count > 2 Then
                        p.MiddleName = st2(2).Trim
                    Else
                        p.MiddleName = ""
                    End If
                    p.LastNameSuffix = st2(0).Trim
                    If st2.Count >= 5 Then
                        p.TestCase = st2(5).Trim
                    End If
                    If st2(3) > "" Then
                        p.AccountNumbersFromCase.Add(st2(3))
                    End If
                    While p.CSVLine.Count < 15
                        p.CSVLine.Add("")
                    End While
                    cases.Add(p)
                End If
            Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                MsgBox("Line " & ex.Message & " is not valid and will be skipped.")
            End Try
            iCount += 1
        End While
    End Using

答案 2 :(得分:0)

这可以正确关闭流:

using(var sw = new StreamWriter(path3))
using(var sr = new StreamReader(path2))
{
    string[] lines = File.ReadAllLines(path);

    foreach (string line in lines)
    {
        string user = sr.ReadLine();

        if (line != user)
        {
            sw.WriteLine(line);
        }
    }
}

有关删除或比较的真实逻辑的帮助,请回答以上El Ronnoco的评论......

答案 3 :(得分:0)

您需要关闭流或使用子句

sw.Close();

using(StreamWriter sw = new StreamWriter(@"c:\test3.txt"))

答案 4 :(得分:0)

您可以使用LINQ ...

class Program
{
    static void Main(string[] args)
    {
        var fullList = "TextFile1.txt".ReadAsLines();
        var removeThese = "TextFile2.txt".ReadAsLines();

        //Change this line if you need to change the filter results.
        //Note: this assume you are wanting to remove results from the first 
        //      list when the entire record matches.  If you want to match on 
        //      only part of the list you will need to split/parse the records 
        //      and then filter your results.
        var cleanedList = fullList.Except(removeThese);

        cleanedList.WriteAsLinesTo("result.txt");
    }
}
public static class Tools
{
    public static IEnumerable<string> ReadAsLines(this string filename)
    {
        using (var reader = new StreamReader(filename))
            while (!reader.EndOfStream)
                yield return reader.ReadLine();
    }

    public static void WriteAsLinesTo(this IEnumerable<string> lines, string filename)
    {
        using (var writer = new StreamWriter(filename) { AutoFlush = true, })
            foreach (var line in lines)
                writer.WriteLine(line);
    }
}

答案 5 :(得分:0)

using(var sw = new StreamWriter(path3))
using(var sr = new StreamReader(path))
{
    string []arrRemove = File.ReadAllLines(path2);
    HashSet<string> listRemove = new HashSet<string>(arrRemove.Count);
    foreach(string s in arrRemove)
    {
        string []sa = s.Split(',');
        if( sa.Count < 2 ) continue;
        listRemove.Add(sa[1].toUpperCase());
    }

    string line = sr.ReadLine();
    while( line != null )
    {
        string []sa = line.Split(',');
        if( sa.Count < 2 )
            sw.WriteLine(line);
        else if( !listRemove.contains(sa[1].toUpperCase()) )
            sw.WriteLine(line);
        line = sr.ReadLine();
    }
}