¿Busca muchas cadenas diferentes en muchos archivos de registro diferentes?

¿Busca muchas cadenas diferentes en muchos archivos de registro diferentes?

Tengo una lista de archivos que han desaparecido en algún lugar de nuestro sistema en el trabajo. También tengo una carpeta llena de 41 archivos de registro que suman 46 MB y que, con suerte, tendrán entradas de registro relacionadas con los archivos que faltan. ¿Cómo podría buscar estos archivos de registro en busca de cualquier valor de mi lista?

La lista está estructurada como un archivo por línea sin extensión de archivo. Los registros parecen tener una estructura, pero todavía no estoy del todo familiarizado con esa estructura. Contiene nombres de archivos y rutas, así como lo que se le hizo.

Sé que puedo almacenar cat *todos los archivos de registro y canalizarlos a grep. Probablemente usaré -Ay -Bpara obtener un poco de contexto de los archivos de registro cuando se encuentre un nombre. Estoy usando GnuWin32 en Windows para poder combinar esto con Powershell, pero creo que hacerlo requeriría que un nombre de archivo contenga los 46 MB y, cuando paso al siguiente nombre de archivo, empiezo de nuevo. Tengo 1830 archivos en la lista, por lo que si tengo que empezar de nuevo con cada uno, terminaré leyendo 46 MB tantas veces que tendré que lidiar con GB de datos repetidos. Parece ineficiente hacerlo de esa manera.

Supongo que podría crear una expresión regular grande de los archivos 1830 o juntarla y ejecutarla una vez en los registros, pero ¿es eso factible? La expresión regular sería de casi 30 KB (1830 archivos * longitud promedio del nombre de archivo de aproximadamente 16 caracteres = 29280 bytes sin mencionar otros 1830 bytes de símbolos de canalización).

Editar:Esto es lo que estoy haciendo ahora cuando estoy en la carpeta de registros y la lista está una carpeta atrás:

$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

Es completamente powershell. Estoy dispuesto a usar cualquier herramienta para acelerar esto porque en este momento hay 550991 líneas en todos los archivos de registro combinados y hay 1830 nombres de archivos, por lo que este enfoque está haciendo1.008.313.530 comparaciones. Todo está en la memoria, así que al menos no tengo E/S de disco que me ralenticen. Es posible que pueda salir de esto whilesi esto ifse vuelve cierto, pero todavía voy a hacer tantas comparaciones que no estoy seguro de si optimizar eso realmente servirá de algo. Ya lleva media hora funcionando. Estoy de acuerdo con reescribir mi enfoque desde la línea 1 si puedo hacerlo antes de irme a casa el fin de semana.

Respuesta1

Sería más eficiente extraer los nombres de los archivos de los registros mediante una expresión regular y ver si cada uno de ellos está en su lista. Podría verse así:

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

Estoy buscando archivos que se parezcan a "\something.txt". Tendrás que cambiar eso.

Si todavía es demasiado lento y su lista de objetos no encontrados es muy grande, entonces podría ser más eficiente cargarlo en un .Net HashSet, pero no lo haría a menos que sea necesario.

información relacionada