3

複数のサブフォルダを持つフォルダがあります。各サブフォルダーには、多くの.dotファイルと.txtファイルが含まれています。

各ファイルを反復処理し、そのファイルの内容でキーフレーズまたはキーワードをチェックする簡単なソリューションがC#.NETにありますか?

Document Name        Keyword1         Keyword2         Keyword3        ...
  test.dot              Y               N                Y

要約すると:

  1. フォルダを選択します
  2. 検索するキーワードのリストを入力してください
  3. 次に、プログラムは各ファイルを検索し、最後に上記のような出力を行います。これを行うことができるので、データグリッドを表示するためのデータテーブルを作成することについて心配する必要はありません。Notepad++のファイル内検索オプションと同様のファイル内検索機能を実行する必要があります

前もって感謝します

4

4 に答える 4

5

必要なのは、ディレクトリ(およびおそらくサブディレクトリ)内のファイルを再帰的に反復することです。

したがって、手順は、.NETのGetfiles()を使用して、指定されたディレクトリ内の各ファイルをループすることです。次に、ディレクトリループが発生した場合は、もう一度ループします。

これは、次のコードサンプルを使用して簡単に実行できます。

  public static IEnumerable<string>  GetFiles(string path)
  {
        foreach (string s in Directory.GetFiles(path, "*.extension_here"))
        {
              yield return s;
        }


        foreach (string s in Directory.GetDirectories(path))
        {
              foreach (string s1 in GetFiles(s))
              {
                    yield return s1;
              }
        }
  }

.NETのディレクトリ内のthrougファイルの反復に関する詳細は、次の場所にあります。

http://blogs.msdn.com/b/brada/archive/2004/03/04/84069.aspx

次に、StringのIndexOfメソッドを使用して、キーワードがファイルに含まれているかどうかを確認します(ReadAllTextの使用はお勧めしません。ファイルのサイズが5 MBの場合、文字列も大きくなります。行ごとのメモリ消費量は少なくなります。 )。

于 2012-10-02T13:22:12.413 に答える
3

Directory.EnumerateFilessearchpatternとrecursivehint( )で使用できますSearchOption.AllDirectories。残りはLINQで簡単です:

var keyWords = new []{"Y","N","Y"};
var allDotFiles = Directory.EnumerateFiles(folder, "*.dot", SearchOption.AllDirectories);
var allTxtFiles = Directory.EnumerateFiles(folder, "*.txt", SearchOption.AllDirectories);
var allFiles = allDotFiles.Concat(allTxtFiles);
var allMatches = from fn in allFiles
                 from line in File.ReadLines(fn)
                 from kw in keyWords
                 where line.Contains(kw)
                 select new { 
                     File = fn,
                     Line = line,
                     Keyword = kw
                 };

foreach (var matchInfo in allMatches)
    Console.WriteLine("File => {0} Line => {1} Keyword => {2}"
        , matchInfo.File, matchInfo.Line, matchInfo.Keyword);

追加する必要があることに注意してくださいusing System.Linq;

行番号を取得する方法はありますか?

行番号だけが必要な場合は、次のクエリを使用できます。

var matches = allFiles.Select(fn => new
{
    File = fn,
    LineIndices = String.Join(",",
                File.ReadLines(fn)
                .Select((l,i) => new {Line=l, Index =i})
                .Where(x => keyWords.Any(w => x.Line.Contains(w)))
                .Select(x => x.Index)),
})
.Where(x => x.LineIndices.Any());

foreach (var match in matches)
    Console.WriteLine("File => {0} Linenumber => {1}"
        , match.File, match.LineIndices);

LINQのクエリ構文ではインデックスを渡すことができないため、少し難しくなります。

于 2012-10-02T13:33:15.270 に答える
2

最初のステップ:すべてのファイルを見つけます。他の人が述べているように、これはSystem.IO.Directory.GetFiles()+ System.IO.File.ReadAllText()を使用して簡単に実行できます。

2番目のステップ:ファイル内のキーワードを検索します。これは、キーワードが1つあり、IndexOf()メソッドを使用して実行できる場合は簡単ですが、ファイルを複数回繰り返す(特にファイルが大きい場合)のは無駄です。

テキスト内の複数のキーワードをすばやく見つけるには、Aho-Corasickオートマトン(アルゴリズム)を使用する必要があると思います。CodeProjectでC#の実装を参照してください:http://www.codeproject.com/Articles/12383/Aho-Corasick-string-matching-in-C

于 2012-10-02T13:28:52.160 に答える
0

ティムの元の回答を使用して行番号を取得する方法は次のとおりです。

var keyWords = new[] { "Keyword1", "Keyword2", "Keyword3" };
var allDotFiles = Directory.EnumerateFiles(folder, "*.dot", SearchOption.AllDirectories);
var allTxtFiles = Directory.EnumerateFiles(folder, "*.txt", SearchOption.AllDirectories);
var allFiles = allDotFiles.Concat(allTxtFiles);
var allMatches = from fn in allFiles
                 from line in File.ReadLines(fn).Select((item, index) => new { LineNumber = index, Line = item})
                 from kw in keyWords
                 where line.Line.Contains(kw)
                 select new
                 {
                     File = fn,
                     Line = line.Line,
                     LineNumber = line.LineNumber,
                     Keyword = kw
                 };

foreach (var matchInfo in allMatches)
    Console.WriteLine("File => {0} Line => {1} Keyword => {2} Line Number => {3}"
        , matchInfo.File, matchInfo.Line, matchInfo.Keyword, matchInfo.LineNumber);
于 2012-10-02T14:09:38.680 に答える