2015-07-30 2 views
5

Я пишу программу, которая поможет мне найти ключевое слово внутри тысяч файлов. У каждого из этих файлов есть ненужные строки, которые мне нужно игнорировать, потому что они воюют с результатами. К счастью, все они расположены после определенной строки внутри этих файлов.
У меня уже есть поиск, не игнорируя строки после этой конкретной строки, возвращая Перечислимые имена файлов, содержащие ключевое слово.Поиск в текстовых файлах для ключевого слова до тех пор, пока не встретится строка

var searchResults = files.Where(file => File.ReadLines(file.FullName) 
              .Any(line => line.Contains(keyWord))) 
              .Select(file => file.FullName); 

Есть ли простой и быстрый способ реализовать эту функциональность? Это не обязательно должно быть в Linq, поскольку я даже не уверен, что это будет возможно.

Редактировать:
Пример, чтобы сделать его более четким. Это как текстовые файлы структурированы:
ххх
ххх
строка
ууу
YYY

Я хочу, чтобы искать ххх линии до тех пор, либо ключевое слово не найдено, или строку, а затем перейдите к следующий файл. Линии yyy, которые я хочу игнорировать в моем поиске.

+0

Моя основная проблема заключается в том, что я не знаю, как игнорировать строки после строки. Поиск строк «yyy» дает слишком много ложных срабатываний в результатах. – drouning

+0

Вы посмотрели на этот вопрос? http://stackoverflow.com/questions/31717324/searching-in-text-files-until-specific-string – Enigmativity

ответ

4

Попробуйте следующее:

var searchResults = files.Where(file => File.ReadLines(file.FullName) 
              .TakeWhile(line => line != "STOP") 
              .Any(line => line.Contains(keyWord))) 
              .Select(file => file.FullName); 
0

, если вы хотите, чтобы удалить определенную строку из довольно большой строки я предпочитаю вы смотрите по ссылке ниже

Fastest way to remove chars from string

Edit: В соответствии с Вашим новым содержанием в вопросе

По для меня мой способ немного примитивен, но имеет вид

string FileString = "Your String to search from"; 
int LastIndexToRead = FileString .IndexOf("Your Specific String"); 
string NewStr = FileString .Substring(0, LastIndexToRead); 

Если вы Ур файл больше, я предлагаю вам разбить строку на несколько частей для лучшей производительности.


Надеюсь, что это помогает

1

Вы можете обрабатывать файлы параллельно, просто добавьте AsParallel() после того, как "файлы". Это должно улучшить скорость обработки файлов. ReadLines не читает весь файл перед поиском, поэтому он должен работать так, как вы ожидаете.

РЕДАКТИРОВАТЬ: извините, неправильно изложите свой вопрос в первый раз и не заметили слово остановки. Учитывая, что я думаю, что было бы легко избежать LINQ:

 IEnumerable<FileInfo> parallelFiles = files.AsParallel(); 
     var result = new ConcurrentBag<string>(); 
     foreach (var file in parallelFiles) 
     { 
      foreach (string line in File.ReadLines(file.FullName)) 
      { 
       if (line.Contains(keyWord)) 
       { 
        result.Add(file.FullName); 
        break; 
       } 
       else if (line.Contains(stopWord)) 
       { 
        break; 
       } 
      } 
     } 
0

Вы могли бы быть в состоянии сделать что-то с Enumerable<string> которые ReadLines возвращается.

Если строки, которые вы можете игнорировать в каждом файле, находятся после определенного номера строки, вы можете отрезать их из Enumerable (вам может потребоваться ToList() или что-то в первую очередь).

Если размещение раздела для игнорирования является динамическим, то предположительно вы можете идентифицировать его из строки заголовка или аналогичного?

Если да, то ваш лучший выбор, скорее всего, в следующем:

  • Открыть файл
    • Читать построчно (вручную)
      • Look "Пропустить здесь" струна
        • Пропустить и прокрутить оставшуюся часть файла
      • Ищите подходящее ключевое слово для поиска.
        • Запись файла в соответствие
+0

Место размещения является динамическим, но это всегда одна и та же строка, поэтому ее можно легко идентифицировать. То, что вы написали, именно то, что я хочу сделать, но возможно ли это в linq? – drouning

1

Это лишь незначительные изменения: игнорировать строки, которые не содержат строку поиска и читать только первое вхождение:

var searchResults = files.Where(file => File.ReadLines(file.FullName) 
              .TakeWhile(line => != myString) 
              .Any(line => line.IndexOf(keyWord) > -1) 
           ) 
         .Select(file => file.FullName); 
+0

Это помогает, но как насчет случаев, когда ключевое слово присутствует только в линиях «yyy»? Это все равно приведет к нескольким ложным срабатываниям. – drouning

+0

Это вы имеете в виду? (См. Править). –

+0

Не совсем, я думаю, ваш код предполагает, что «myString» всегда присутствует в строках, которые я хочу игнорировать, но это не тот случай. «myString» - это одна строка в файлах, которые служат разделителем. Я хотел бы игнорировать каждую строку после «myString», даже если она содержит ключевое слово. – drouning