Powershell: es necesario analizar un file de text y pasar al correo electrónico

Tengo un file de text muy básico que contiene nombres de usuario. Necesito poder search cada sección que comienza con "Usuario bsmith" (por ejemplo), copyr todo el text que sigue y terminar en la línea anterior al siguiente "Usuario XXXX" (User tford, por ejemplo a continuación). Luego pegaré el text copydo en el cuerpo de un correo electrónico. Ya he escrito Powershell para crear el correo electrónico y enviarlo. Solo necesito escribir la parte para tomar el text del file de text listdo. Todavía es nuevo en la progtwigción, por lo que es difícil determinar la forma de search y copyr desde el file .txt y pegarlo en el cuerpo del correo electrónico. Svnlog.txt es el file que se analiza. Puedo get todo el contenido, pero necesito poder search secciones para cada "Usuario XXXX" para el próximo "Usuario XXX".

$olComObject = new-object -comobject outlook.application $svn = (Get-Content C:\Dev\Powershell\svnlog.txt) -join "`n" $NewMail = $olComObject.CreateItem(0) $NewMail.Subject = "Testing Voting Options" $NewMail.Body = "Please use the attached voting buttons in this email to acknowledge or reject if the following user permissions are correct!" + "`n" + $svn $NewMail.To = "[email protected];[email protected]" $NewMail.VotingOptions = "Accept;Reject" $NewMail.Send() 

Estaba pensando en posiblemente search el grupo "Usuario XXX" usando lo siguiente, pero nuevamente no estoy seguro si esta es la ruta correcta para ir o incluso funcionará.

 $fullsvn = Get-Content "C:\Dev\Powershell\svnlog.txt" Out-File () "C:\Dev\Powershell\svnlogBSmith.txt" 

El formatting del contenido del file de text es el siguiente.

Usuario BSmith

repos

[functionalSpecs: /]

@admins = rw

@dba = r

@hca = rw

@businessAnalysts = rw

@qa = rw

@portal = rw

@intercept = rw

@pmo = rw

[restrictedDocs: / softtek]

@restrictedDocs = rw

Grupos

BusinessAnalysts = ajones, pjohnson, ssmith, rjackson,

@pmo = lferguson

Usuario tford

De acuerdo. Así que probé la ruta de TessellatingHeckler. Sin embargo, no parece estar marcando las líneas con el nombre de usuario (en este caso es TKelems en lugar de BSmith). Aquí está mi código actual y un ejemplo de la salida que obtengo en la console.

 Get-Content C:\Dev\Powershell\svnlog.txt | foreach { if ($_ -match '^User (.*)') { $tag = $matches[1] } [Management.Automation.PSObject]@{ Tag=$tag Item=$_ } } $TKelems | Where Tag -EQ 'tkelems' Out-File "C:\Dev\Powershell\svnlogTKelems.txt" -InputObject $TKelems 

Salida:

Nombre Valor
—- —–
Etiqueta
Ít ————————————————- ——————————-
Etiqueta
Usuario del artículo
Etiqueta
Artículo tkelems:
Etiqueta
ít.
Etiqueta
Artículo Repos
Etiqueta
Ít ——————–
Etiqueta
Artículo [functionalSpecs: /]
Etiqueta
Artículo @admins = rw
Etiqueta
Artículo @eclas = rw
Etiqueta
Artículo @cfis = rw
Etiqueta
Artículo @transMgmt = rw
Etiqueta
Artículo @dba = r
Etiqueta
Artículo @hca = rw
Etiqueta
Artículo @businessAnalysts = rw
Etiqueta
Artículo @qa = rw
Etiqueta
Artículo @portal = rw
Etiqueta
Artículo @intercept = rw
Etiqueta

También olvidé agregar el contenido del Ou-File creado en la última línea. No estoy seguro de qué hacer con esto tampoco. Básicamente, no se muestran tags en la console, y el file de salida muestra algo totalmente diferente (consulte a continuación):

IsReadOnly: falso

IsFixedSize: False

IsSinnchronized: False

Teclas: {Tag, Item}

Valores: {$ null, ——————————————– ————————————}

SyncRoot: System.Object

Cuenta: 2

IsReadOnly: falso

IsFixedSize: False

IsSinnchronized: False

Teclas: {Tag, Item}

Valores: {$ null, Usuario}

SyncRoot: System.Object

Cuenta: 2

Una opción:

 $textfile = 'c:\testfiles\test.txt' $Search = 'BSmith' $Found = (Get-Content $textfile -Raw) -split '(?ms)^(?=User)' -like "User $Search*" 

Esto leerá el file de text en una sola cadena, luego lo dividirá en las líneas que comienzan con "Usuario", y filtrará aquellas que no concuerden con el nombre de usuario en $ Search.

Necesitará agregar trampas de error para verificar que $ found esté vacío, o devolver resultados múltiples y manejarlos para adaptarlos.

algo como esto podría ser un punto de partida

 $usernameregex = 'bsmith' $found = $false Get-Content "C:\Dev\Powershell\svnlog.txt" | % { if (!$found -and $_ -match "^user $username$") { $found = $true Write-Output '' Write-Output $_ } elseif ($found -and $_ -match '^user ') { if (!($_ -match "^user $username$")) { $found = $false } elseif ($_ -match "^user $username$") { Write-Output '' Write-Output $_ } else { Write-Output '' } } elseif ($found) { Write-Output $_ } } | select -skip 1 | Set-Content "C:\Dev\Powershell\svnlogBSmith.txt" 

para verificar múltiples nombres, cambie el $ usernameregex a este

 $usernameregex = (bsmith|tford) 

He visto esto: " Quiero líneas en un file de [encabezado de sección] a la siguiente [encabezado de sección] " antes, y la respuesta de mjolinor con la expresión regular de línea múltiple es breve y efectiva, pero no creo que esté muy claro qué es haciendo y por qué. Y no funcionará tan bien en una serie general de cadenas sin -join primero.

Como alternativa, me gusta bastante el concepto de labelr cada línea, luego puede agrupar o filtrar por la label. por ejemplo, retire el nombre de usuario y etiquete cada línea con el nombre de usuario visto por última vez:

 gc .\log.txt | foreach { if ($_ -match '^User (.*)') { $tag = $matches[1] } [pscustomobject]@{ Tag=$tag Item=$_ } } 

Lo que hace con tu file es este:

 Tag Item ---- ---- BSmith User BSmith BSmith repos BSmith [functionalSpecs:/] BSmith @admins = rw BSmith @dba = r BSmith @hca = rw BSmith @businessAnalysts = rw BSmith @qa = rw BSmith @portal = rw BSmith @intercept = rw BSmith @pmo = rw BSmith [restrictedDocs:/softtek] BSmith @restrictedDocs = rw BSmith Groups BSmith BusinessAnalysts = ajones, pjohnson, ssmith, rjackson, BSmith @pmo = lferguson tford User tford tford 

Entonces puedes fácilmente:

 $that | Where Tag -eq 'BSmith' 

o

 $that | group Tag 

Podría labelr líneas con cualquier coincidencia de expresión regular para los delimitadores de sección.

[Editar: se agregó ^ a la expresión regular, sugerida por @mjolinor]