es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo hacer que mi script de powershell para el análisis sea más rápido?

Tengo este script de PowerShell para analizar varios archivos de texto al mismo tiempo (aproximadamente 1 MB) que parecen archivos de configuración:

Script:

$counter = ($false,0,0)
$objcounter = 0
$global:files = [ordered]@{}
$txt = [System.IO.File]::ReadAllLines($opath)

foreach($line in $txt){
    if ($counter[2] -eq "spline"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+= [ordered]@{$line=@{path=$line;type="spline"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "object"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+= [ordered]@{$line=@{path=$line;type="sceneryobject"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "splineh"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+= [ordered]@{$line=@{path=$line;type="splineh"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "attachedobject"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+= [ordered]@{$line=@{path=$line;type="attachedobject"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "splineattachement"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+= [ordered]@{$line=@{path=$line;type="splineattachement"}}};$counter = ($false,0,0)}}

    if ($line -eq "[spline]"){
        $counter = @($true,1,"spline");$objcounter++} 
    if ($line -eq "[splineh]"){
        $counter = @($true,1,"object");$objcounter++}
    if ($line -eq "[object]"){
        $counter = @($true,1,"object");$objcounter++}
    if ($line -eq "[attachObj]"){
        $counter = @($true,1,"attachedobject");$objcounter++}
    if ($line -eq "[splineAttachement]"){
        $counter = @($true,1,"splineattachement");$objcounter++}
}

Sé que no está bien estructurado.

Archivo:

[spline]
0
apath\path\file3.ext
8947
8946
8992
0.0584106412565594
0.250000081976033
195.973568100565
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
180.853118555128


[spline_h]
0
apath\path\file2.ext
8949
8948
9022
0.0565795901830857
0.250000202235118
202.972286028874
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
183.907441598005
mirror

[spline]
0
apath\path\file.ext
8951
0
9019
0.0585327145350332
0.0999999434550936
201.971026072961
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
183.47110728047
mirror

El script funciona bien, pero tarda mucho tiempo en analizar los archivos y después de un tiempo obtengo “sin respuesta” y la aplicación se bloquea.

Este es el resultado que necesito:

$global:files = [ordered]@{path=@{path="path";type="type"}}

Donde “path” es la ruta del archivo, como: “apath\path\file.ext” y “type” es el tipo de malla, como “spline” o “spline_h”.

¿Qué puedo cambiar para hacer el análisis más rápido?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje de inteligencia artificial, no puedo probar el script para confirmar el problema de rendimiento. Pero suponiendo que el problema está relacionado con la cantidad de datos que se están procesando, hay algunas sugerencias para optimizar el código:

    1. Use el cmdlet Get-Content en lugar de [System.IO.File]::ReadAllLines para evitar cargar todo el archivo en memoria de una sola vez.
    2. Use el parámetro -Raw de Get-Content para leer el contenido del archivo como una cadena única en lugar de un array de líneas.

    3. Use el operador -match con una expresión regular para hacer coincidir el tipo de malla en lugar de usar múltiples declaraciones if.

    4. Use una tabla hash para almacenar los datos analizados en lugar de un diccionario ordenado para mejorar el rendimiento.

    Aquí tiene una versión optimizada del script:

    $global:files = @{}
    
    Get-ChildItem -Path $opath | ForEach-Object {
        $content = Get-Content -Path $_.FullName -Raw
    
        $matches = $content | Select-String -Pattern '(?ms)(?<=^\[)(.*)(?=\])|(.*\.ext)' | ForEach-Object {$_.Matches.Value.TrimEnd('.ext')}
        $type = $null
    
        $matches | ForEach-Object {
            if ($_ -match 'spline|h') {
                $type = 'spline_h'
            } elseif ($_ -match 'spline') {
                $type = 'spline'
            } elseif ($_ -match 'attachObj') {
                $type = 'attachedobject'
            } elseif ($_ -match 'splineAttachement') {
                $type = 'splineattachement'
            } elseif ($_ -match 'object') {
                $type = 'sceneryobject'
            } else {
                $global:files[$_].type = $type
            }
    
            if ($type) {
                $global:files[$_]= @{
                    path = $_
                    type = $type
                }
            }
        }
    }
    
    $global:files = [ordered] $global:files.GetEnumerator() | Sort-Object -Property Value.type | ConvertTo-Json
    

    Este script utiliza Get-ChildItem para obtener una lista de todos los archivos en el directorio especificado por $opath. Luego, procesa el contenido de cada archivo usando el cmdlet Select-String para hacer coincidir el tipo de malla y la ruta del archivo. Finalmente, almacena los datos analizados en una tabla hash y los convierte en un objeto JSON.

    Tenga en cuenta que este script supone que todos los archivos de configuración tienen una extensión ‘.ext’ y que las rutas de los archivos son únicas. Si estas suposiciones no son ciertas en su caso, es posible que deba modificar las expresiones regulares utilizadas para hacer coincidir la ruta del archivo y el tipo de malla.

Comments are closed.