Remove duplicate 串s from CSV

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
你好
我有来自ERP系统的CSV文件,尽管系统存在错误(等待修复),偶尔它会发送包含福彩12选5走势图行的CSV文件的文件,这会导致其他系统混乱它导入到。
但是,我应该在几周内解决ERP的问题。

我如何创建一个简单的控制台文件,该文件检查文件夹中是否有CSV文件并读取该文件,并检查第二行是否与前两行匹配?如果是这样,它只会删除最后一行。
下面的csv示例
"P0755","R190830022","2021-08-30","POSITIVE RELEASE",57.000,"TRUE"
"P0755","R190830022","2021-08-30","POSITIVE RELEASE",14.500,"TRUE"

我基本上希望应用程序删除第二行作为"" match.

任何帮助将不胜感激或示例。
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
现在一切都很好。我将其更改为直接从路径读取,而不是在CMD中提示输入路径。
非常感谢您抽出宝贵时间来帮助我。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
That's no bother. Glad to help, and if you want to work towards simplifying the code, you can use the two lines i last gave you and change 串[] csvReader, to a hashset and use lines 44 with a little tweak to remove the duplicates. You'd do the whole lot in about 5 lines or so. ;)
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
如果您相信LINQ,这是另一种方法:

C#:
class RowComparer : IEqualityComparer<string>
{
    public bool Equals(string x, 串 y) => GetHashCode(x) == GetHashCode(y);

    public int GetHashCode(string obj)
    {
        //$ TODO: need to replace this parsing with more robust parsing to handle quotes
        串 key = obj?.Split(',')
                        ?.Skip(1)
                        ?.FirstOrDefault();
        return key?.GetHashCode() ?? 0;
    }
}
:

File.WriteAllLines(tempFileName,
                  File.ReadLines(originalFileName)
                      .Distinct(new RowComparer()));
File.Replace(tempFileName,originalFileName,null);
File.Delete(tempFileName);

:

注意:上面未经​​测试的代码,只是我在等待构建完成时在键盘上设计的。
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
酷,我会玩的。
现在说我想
1.删​​除福彩12选5走势图项,但将其移到单独的CSV文件中 :) (只是福彩12选5走势图项)。最好的方法是什么?
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
或者,如果更容易(虽然听起来更难)
从福彩12选5走势图行中提取数量,并将其添加到其他匹配行的数量中。 ;)
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
使用您拥有的内容并学习对其进行编辑。查看在何处处理福彩12选5走势图项值得一提。这样一来,就可以读取文件writealltext了。

@跳伞 不知道是否是因为我在移动,但这看起来像很多文字。再次看,它可以缩短。将文件行读取到列表,其中不包括福彩12选5走势图行和带有linq的空行

手机回覆
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
No need to read into a list. File.ReadLines() returns an IEnumerable<string>. File.WriteAllLines() also takes an IEnumerable<string>. All that is needed is a way to find the unique lines. Thate is where the LINQ Distinct() extension come in. It does all the magic you did with your HashSet in your original code (in fact if you look at the reference sources, it also uses a HashSet. All that is missing is to be able to tell Distinct() how to compare two different lines to see if they are the same or different. That is where the RowComparer which implements the IEqualityComparer comes in. This is what does the line parsing and pulls out the second column value and checks for equality.
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
在看到我的比较器以及Jon Skeet的比较器之后,我想出了以下这种混合形式:
C#:
类比较器<T, TKey> : IEqualityComparer<T>
{
    功能<T, TKey> _getKey;

    公共比较器(Func<T, TKey> getKey) => _getKey = getKey;
    公共布尔等于(T x,T y)=>_getKey(x)== _getKey(y);
    公共诠释GetHashCode(T obj)=>_getKey(obj).G​​etHashCode();
}

:
var comparer = new Comparer(r => r.Split(',')
                                  .ElementAtOrDefault(1)
                                  ?? "");
File.WriteAllLines(tempFileName,
                   File.ReadLines(originalFileName)
                       .Distinct(comparer));
File.Replace(tempFileName,originalFileName,null);
File.Delete(tempFileName);
:

同样,未经测试的代码。只是在键盘上涂鸦。
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
class Comparer<T, TKey> : IEqualityComparer<T>
{
功能<T, TKey> _getKey;

公共比较器(Func<T, TKey> getKey) => _getKey = getKey;
公共布尔等于(T x,T y)=>_getKey(x)== _getKey(y);
公共诠释GetHashCode(T obj)=>_getKey(obj).G​​etHashCode();
}

:
var comparer = new Comparer(r => r.Split(',')
.ElementAtOrDefault(1)
?? "");
File.WriteAllLines(tempFileName,
File.ReadLines(originalFileName)
.Distinct(comparer));
File.Replace(tempFileName,originalFileName,null);
File.Delete(tempFileName);
:
嗨跳伞
我将其粘贴到控制台中,但全部变为红色。
我要去哪里错了?不好意思

1570786308185.png
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
我猜这很奇怪。我不知道类是否可以驻留在方法内部,可以吗?

在这里,必须了解应用程序的基本构建块。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
在看到我的比较器以及Jon Skeet的比较器之后,我想出了以下这种混合形式:
我仍然希望使用groupby,select,distinct。如果我可以避免编写比较器,那我会的。

我猜每个人都自己。
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
抱歉-我只是在学习,我真的很努力! :(
这是我的代码。对于每个福彩12选5走势图项,我都需要福彩12选5走势图行来删除并进入其自己的单独CSV文件。整天都在尝试,但我却做不到。

这是我的代码
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace CSVRemoveDuplicates
{
 
        class Program
        {
            static 串 pathToFolder = @"C:\Users\tdignan\Documents\CSV TEST";
            private static void Main(string[] args)
            {
                // Console.WriteLine("Press Ctrl+V to paste in your path and press enter key :");
                /* After you Ctrl+V, and hit enter, pathToFile will be set to the directory of your CSV files */
                // pathToFolder = Console.ReadLine();
                DirectoryInfo directory = new DirectoryInfo(pathToFolder);
                foreach (FileInfo file in directory.GetFiles("*.csv"))
                {
                    RemoveDuplicates_InEachFile(file.FullName, file.Name);
                }
            }
            private static void RemoveDuplicates_InEachFile(string pathToFile, 串 filename)
            {
                // Below was put into file incase wanted CSV to go to a seperate directory. Easier if it is is within the same directory.
                串 pathtoFile2 = @"C:\Users\tdignan\Documents\CSV TEST\STOCKRD" + DateTime.Now.ToFileTime() + ".csv";

                HashSet<string> hashSet = new HashSet<string>();
                /* Above are self explanatory, while below csvReader creates an array of 串s from all lines in the file */


                IEnumerable<string> eachBlankLine = File.ReadAllLines(pathToFile).Where(emptyLine => !string.IsNullOrWhiteSpace(emptyLine));
                File.WriteAllLines(pathToFile, eachBlankLine);
                串[] csvReader = File.ReadAllLines(pathToFile);
                /* Loop the 串 array of lines */
                foreach (string line in csvReader)
                {
                    /* Split at second comma, by skipping the first one */
                    串 partB = line.Split(',').Skip(1).FirstOrDefault();
                    bool hasText = hashSet.Any(Func_Partial => 功能_Partial.Contains(partB));
                    if (hasText == false)
                    {
                        /* If it isn't added, we will add it below */
                        hashSet.Add(line);



                        /* Next we add line to the hash set */
                    }
                    else
                    {


                    }
                }
            /* Delete the file, and recreate it by appending it */

            //   File.Delete(pathToFile);
            //File.Delete(pathToFile);
            File.Delete(pathToFile);
            File.WriteAllLines(pathtoFile2, eachBlankLine);
          
            
      


          
            hashSet.ToList().ForEach(func_line => File.AppendAllText(pathToFile, 串.Concat(func_line, Environment.NewLine)));
            
            // System.IO.File.WriteAllText(pathToFile, pathToFile);

            /* Lastly write the file back with only the entries we added, and no duplicates */
        }
        }
    }
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
我设法让它创建了一个单独的CSV文件,但是如果没有福彩12选5走势图,它仍然会使用来自CSV的数据创建一个新的CSV文件,无论是否福彩12选5走势图。
该代码将移动福彩12选5走势图项,但也将福彩12选5走势图项保留在原始文件中。
我需要它来删除原始文件中的福彩12选5走势图项,并且不为任何记录创建任何新的CSV文件(如果没有福彩12选5走势图项)

干杯!
谢谢你的耐心!
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
我什至看不到您如何设法弄乱了该代码,即使注释告诉您什么是什么……总之,请尝试一下。我只是很快地写了它,还没有测试它,但是它应该可以工作,它还将把您的副本存储在一个copys文件夹中,在该文件夹中它可以从原始目录中读取文件。请注意,如果文件存在,它将不会覆盖它们。 :
C#:
        const 串 pathToFolder = @"C:\Users\user\Downloads\CSV Script\";
        const 串 pathNewDir = "Copies";
        private static void Main(string[] args)
        {
            DirectoryInfo directory = new DirectoryInfo(pathToFolder);
            FileInfo[] array = directory.GetFiles("*.csv");
            for (int i = 0; i < array.Length; i++)
            {
                FileInfo file = array[i];
                RemoveBlanks_InEachFile(file.FullName, Path.Combine(pathToFolder, pathNewDir, file.Name));
            }
        }
        private static void RemoveBlanks_InEachFile(string pathToFile, 串 pathOfCopies)
        {
            var existingPath = Path.GetDirectoryName(pathOfCopies);
            if (!Directory.Exists(existingPath))
                Directory.CreateDirectory(existingPath);
            IEnumerable<string> nonBlankLine = File.ReadAllLines(pathToFile).Where(nonEmptyLine => !string.IsNullOrWhiteSpace(nonEmptyLine));
            AddNon_Duplicated(nonBlankLine, pathOfCopies, null);
        }

        private static void AddNon_Duplicated(IEnumerable<string> nonBlankLine, 串 pathOfCopies, HashSet<string> hashSet_Filter)
        {
            hashSet_Filter = new HashSet<string>();
            foreach (var non_Duplicate in from 串 line in nonBlankLine
                                          let partB = line.Split(',').Skip(1).FirstOrDefault()
                                          let hasText = hashSet_Filter.Any(Func_Partial => 功能_Partial.Contains(partB))
                                          where hasText == false
                                          select line)
            {
                hashSet_Filter.Add(non_Duplicate);
            }
            Write_IEnumerableValues(pathOfCopies, hashSet_Filter);
        }
        private static void Write_IEnumerableValues(string writeTo, IEnumerable<string> newValues)
        {
            File.WriteAllLines(writeTo, newValues);
        }
我会假设您正在使用任何其他应用程序。导入这些新的CSV文件后,您将迭代目录并删除每个文件。
 
Last edited:

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
谢谢
我需要它来删除原始文件中的福彩12选5走势图记录,否则ERP系统将处理原始文件中的交易;以及新的。
如果文件中没有福彩12选5走势图项,我还需要它也不要创建第二个文件。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
我这样做是因为将福彩12选5走势图项添加到新文件中没有任何意义。如果要将福彩12选5走势图的值导入另一个系统,为什么会需要福彩12选5走势图的值?

您开始询问如何删除/删除福彩12选5走势图项,然后再次询问将其添加到新文件中。在打开的帖子中准确说明您想要的内容,而不用改变主意。
好的,您可以选择任何一种方式。您想要一个新文件还是删除第二行?
是的,请删除。
如所引用的,这不是您刚开始要求的。很抱歉,如果我最初误解了,但这是改变主意的麻烦,或者一开始的描述不够充分。
我需要福彩12选5走势图的行才能删除并进入其自己的单独CSV文件
I deliberately compartmentalised the latest code into methods since your last attempt is all messed up, and so you can see where the work is being done. And if you want the duplicates only, you can acquire them at : foreach (var non_Duplicate in from 串 line in nonBlankLine, and pass them onto your writing method private static void Write_IEnumerableValues with the path(s) you want to use. You can extend the method to accommodate another 串 to accept a second path to write for your duplicates file path, and also add an additional IEnumerable<string>用于收集福彩12选5走势图项。

考虑一下;如果我给您的内容已经占用了csv中不包含非福彩12选5走势图值的所有行,那么您认为现在需要更改什么才能只获得福彩12选5走势图值呢?
 
最佳 底部