Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 统计列表中字符串的出现次数并在控制台中显示_C#_Linq_File - Fatal编程技术网

C# 统计列表中字符串的出现次数并在控制台中显示

C# 统计列表中字符串的出现次数并在控制台中显示,c#,linq,file,C#,Linq,File,我现在正在创建一个Logparser,我能够逐行检查文件夹中的所有文件,并提取我想要的子字符串,它是“fct=“之后的值。所有这些都使用Regex,我将结果放入列表中。 现在我想计算列表中每个字符串的出现次数并显示它 我使用的是GroupBy,但当我显示结果时,所有出现的内容都在1 实际值: 720 1x 720 1x 710 1x class Program { static void Main(string[] args) { int cou

我现在正在创建一个Logparser,我能够逐行检查文件夹中的所有文件,并提取我想要的子字符串,它是
“fct=“
之后的值。所有这些都使用
Regex
,我将结果放入
列表中。
现在我想计算列表中每个字符串的出现次数并显示它

我使用的是GroupBy,但当我显示结果时,所有出现的内容都在
1

实际值:

 720 1x
 720 1x
 710 1x
   class Program
{

    static void Main(string[] args)
    {

        int counter = 0;
        string[] dirs = Directory.GetFiles(@"C:/LogParser/LogParserV1", "*.txt");
        StreamWriter sw = new StreamWriter("C:/LogParser/LogParserV1/test.txt");      
        char[] delimiters = { '<', ',', '&', ':', ' ', '\\', '\'' };
        string patternfct = "(?<=FCT=)[0-9]*";


        foreach (string fileName in dirs)
        {
            StreamReader sr = new StreamReader(fileName);

            {
                String lineRead;
                while ((lineRead = sr.ReadLine()) != null)
                {

                    //To find all the value of fct= occurence 
                    var listfct = Regex.Matches(lineRead, patternfct, 
  RegexOptions.IgnoreCase).Cast<Match>().Select(x => x.Value).ToList();


                   var fctGroups = listfct.GroupBy(i => i);
                    foreach (var grp in fctGroups)
                    {
                        var fct = grp.Key;
                        var total = grp.Count();
                        System.Console.WriteLine("fct=" + fct + " " + "Total=" + total);
                    }

                    counter++;
                }
                System.Console.WriteLine(fileName);

                sr.Close();
                sw.Close();
            }
        }

        // Suspend the screen.  
        System.Console.ReadLine();

    }
}
}
FCT=10019 2x
FCT=4515 1x
它应该是:

 720 2x
 710 1x  
我发现问题在于我逐行读取文件,因此如果同一行上的
“fct=“
值不是两次,则不会将其计算为
2
,而是仅将其显示的每一行计算为
1

所以我需要找到一种方法来计算我的列表,而不是一行一行地计算我的文件

我真的是初学者,所以不知道如何做到这一点,任何提示将被感激

以下是日志数据示例:

<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC</dat></logurl>
<dat>XN=KEY,CN=RTU FCT=4515</dat>LBZ=test.sqi</logurl>
<dat>XN=KEY,CN=RT</dat>FCT=10019</logurl>
我的代码:

 720 1x
 720 1x
 710 1x
   class Program
{

    static void Main(string[] args)
    {

        int counter = 0;
        string[] dirs = Directory.GetFiles(@"C:/LogParser/LogParserV1", "*.txt");
        StreamWriter sw = new StreamWriter("C:/LogParser/LogParserV1/test.txt");      
        char[] delimiters = { '<', ',', '&', ':', ' ', '\\', '\'' };
        string patternfct = "(?<=FCT=)[0-9]*";


        foreach (string fileName in dirs)
        {
            StreamReader sr = new StreamReader(fileName);

            {
                String lineRead;
                while ((lineRead = sr.ReadLine()) != null)
                {

                    //To find all the value of fct= occurence 
                    var listfct = Regex.Matches(lineRead, patternfct, 
  RegexOptions.IgnoreCase).Cast<Match>().Select(x => x.Value).ToList();


                   var fctGroups = listfct.GroupBy(i => i);
                    foreach (var grp in fctGroups)
                    {
                        var fct = grp.Key;
                        var total = grp.Count();
                        System.Console.WriteLine("fct=" + fct + " " + "Total=" + total);
                    }

                    counter++;
                }
                System.Console.WriteLine(fileName);

                sr.Close();
                sw.Close();
            }
        }

        // Suspend the screen.  
        System.Console.ReadLine();

    }
}
}
FCT=10019 2x
FCT=4515 1x
类程序
{
静态void Main(字符串[]参数)
{
int计数器=0;
字符串[]dirs=Directory.GetFiles(@“C:/LogParser/LogParserV1”,“*.txt”);
StreamWriter sw=新的StreamWriter(“C:/LogParser/LogParserV1/test.txt”);
char[]分隔符={'x.Value).ToList();
var fctGroups=listfct.GroupBy(i=>i);
foreach(fctGroups中的var grp)
{
var fct=grp.Key;
var total=grp.Count();
System.Console.WriteLine(“fct=“+fct+”+“Total=“+Total”);
}
计数器++;
}
System.Console.WriteLine(文件名);
高级关闭();
sw.Close();
}
}
//暂停屏幕。
System.Console.ReadLine();
}
}
}

您可以尝试在Linq的帮助下查询数据:

using System.Linq;
using System.Text.RegularExpressions;

...

Regex regex = new Regex("(?<=FCT=)[0-9]*", RegexOptions.IgnoreCase);

var records = Directory
  .EnumerateFiles(@"C:/LogParser/LogParserV1", "*.txt")
  .SelectMany(file => File.ReadLines(file))
  .SelectMany(line => regex
     .Matches(line)
     .Cast<Match>()
     .Select(match => match.Value))
  .GroupBy(number => number)
  .Select(group => $"FCT={group.Key} {group.Count()}x");

foreach (string record in records)
  Console.WriteLine(record);
但是添加了
测试行

  string[] testLines = new string[] {
    "<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC</dat></logurl>",
    "<dat>XN=KEY,CN=RTU FCT=4515</dat>LBZ=test.sqi</logurl>",
    "<dat>XN=KEY,CN=RT</dat>FCT=10019</logurl>",
  };

  Regex regex = new Regex("(?<=FCT=)[0-9]*", RegexOptions.IgnoreCase);

  var records = testLines
    .SelectMany(line => regex
       .Matches(line)
       .Cast<Match>()
       .Select(match => match.Value))
    .GroupBy(number => number)
    .Select(group => $"FCT={group.Key} {group.Count()}x");

  foreach (string record in records)
    Console.WriteLine(record);
编辑:如果要在
记录中包含
文件
,可以使用匿名对象:

var records = Directory
  .EnumerateFiles(@"C:/LogParser/LogParserV1", "*.txt")
  .SelectMany(file => File
     .ReadLines(file)
     .Select(line => new {
        file = file,
        line = line,  
      }))
  .SelectMany(item => regex
     .Matches(item.line)
     .Cast<Match>()
     .Select(match => new {
        file   = item.file,
        number = match.Value  
      }))
  .GroupBy(item => new {
     file   = item.file, 
     number = item.number
   })
  .OrderBy(group => group.Key.file)
  .ThenBy(group => group.Key.number)
  .Select(group => $"{group.Key.file} has FCT={group.Key.number} {group.Count()}x")
var记录=目录
.Enumerate文件(@“C:/LogParser/LogParserV1”,“*.txt”)
.SelectMany(文件=>file
.ReadLines(文件)
.选择(行=>新建{
file=file,
行=行,
}))
.SelectMany(项=>regex
.匹配项(项.行)
.Cast()
.选择(匹配=>新建){
file=item.file,
数字=匹配。值
}))
.GroupBy(项目=>新建){
file=item.file,
编号=项目编号
})
.OrderBy(group=>group.Key.file)
.ThenBy(group=>group.Key.number)
.Select(group=>$“{group.Key.file}具有FCT={group.Key.number}{group.Count()}x”)

您能提供您正在解析的日志数据吗?这样您的代码就可以逐行计算您的文本了。你想一个文件一个文件地数数吗?您只需要有一个局部变量countText,并在while循环中累积它countText+=grp.Count()@乔尔·德斯劳瑞尔:很抱歉我的打字错误,它应该是
.EnumerateFiles
而不是
EnumerateDirectory
我只看到一件似乎不起作用的事情,我需要FCT=忽略我以前使用的区分大小写的RegexOptions。Ignorecase但我似乎无法将它放在您的查询中任何想法?@Joel Deslauriers:
Regex Regex=new Regex(“(?很好,它工作得很好,但我也能够使用Directory.GetFiles获得每个文件的名称。您知道我是否可以对EnumerateFiles执行相同的操作吗?
EnumerateFiles
一个接一个地返回文件,此时
GetFiles
获取所有文件并将其作为数组返回。我们不想等到所有文件都已获取(
GetFiles
)我们可以从第一个文件开始(
EnumerateFiles