Ищете множество разных строк в разных файлах журналов?

Ищете множество разных строк в разных файлах журналов?

У меня есть список файлов, которые где-то пропали в нашей системе на работе. У меня также есть папка, полная 41 файла журнала, в сумме до 46 МБ, которые, как я надеюсь, содержат записи журнала, относящиеся к пропавшим файлам. Как мне выполнить grep этих файлов журнала на предмет любого значения в моем списке?

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

Я знаю, что могу cat *все файлы журналов и передать их в grep. Я, вероятно, буду использовать -Aи , -Bчтобы получить немного контекста из файлов журналов, когда имя найдено. Я использую GnuWin32 в Windows, поэтому я мог бы связать это с Powershell, но я думаю, что это потребовало бы, чтобы одно имя файла обрабатывало все 46 МБ, и когда я перехожу к следующему имени файла, я начинаю все заново. У меня в списке 1830 файлов, поэтому если мне придется начинать заново с каждого из них, я в конечном итоге буду читать 46 МБ так много раз, что буду иметь дело с ГБ повторяющихся данных. Кажется, делать это таким образом неэффективно.

Я полагаю, что я мог бы создать большое регулярное выражение из 1830 файлов или объединенных вместе и запустить его один раз против журналов, но осуществимо ли это? Регулярное выражение будет почти 30 КБ (1830 файлов * средняя длина имени файла около 16 символов = 29280 байт, не говоря уже о еще 1830 байтах символов конвейера).

Редактировать:Вот что я делаю сейчас, когда нахожусь в папке журналов и список сместился на одну папку назад:

$logs = gc *
$notfound = gc ../notfound.txt
$logs | % { $i = 0; while ($i -lt $notfound.Count) { if ($_ -contains $notfound[$i]) { echo $_ }; $i++; } } | out-file C:\discovered.txt

Это полностью powershell. Я готов использовать любой инструмент, чтобы ускорить это, потому что сейчас во всех файлах журнала вместе взятых 550991 строк и 1830 имен файлов, так что этот подход делает1,008,313,530 сравнений. Все это в памяти, так что, по крайней мере, у меня нет дискового ввода-вывода, который бы меня замедлял. Я мог бы вырваться из , whileесли ifстанет истинным, но я все равно собираюсь сделать так много сравнений, что не уверен, принесет ли это какую-либо пользу. Он уже работает полчаса. Я согласен переписать свой подход из строки 1, если я смогу сделать это до того, как поеду домой на выходные.

решение1

Было бы эффективнее вытащить имена файлов из журналов с помощью регулярного выражения и посмотреть, есть ли каждый из них в вашем списке. Это может выглядеть примерно так:

$notfound = gc ../notfound.txt
gc * |
        select-string -AllMatches '\\(?<filename>[^\\]+)\.txt' | 
        select -ExpandProperty Matches |
        % { $_.Groups['filename'].Value } |
        ? { $notfound -contains $_ } |
        out-file C:\discovered.txt

Я ищу файлы, которые выглядят как "\something.txt". Вам придется это изменить.

Если он все еще слишком медленный, а ваш список notfound очень большой, то, возможно, более эффективным будет загрузить его в .Net HashSet, но я бы не советовал делать этого без крайней необходимости.

Связанный контент