Regex, PowerShell, How can I get this to show up in PowerShell? - string

In using the following PowerShell Script with Regex.
THE PROBLEM: I don't get any data returned for the Filename.
CURRENT RESULTS IN POWERSHELL:
EXPECTED RESULTS IN POWERSHELL:
This Regex Demo is doing what I would think it should be doing in Regex. (Originating from this question.)
POWERSHELL SCRIPT:
$InStuff = #('111111_SMITH, JIM_END TLD 6-01-20 THR LEWISHS.pdf','222222_JONES, MIKE_G URS TO 7.25 2-28-19 SA COOPSHS.pdf')
switch -Regex ($instuff) {
'^(^.{0,6})*|(?!.*_).*(?=\.)'{
[pscustomobject]#{
EmployeeID = $matches.1
FileName = $matches.2
}
}
}
QUESTION:
What do I need to change to get the filename to show up in the PowerShell results?

Seems like a simple .Split() can achieve what you're looking for. The method will split the string into 3 tokens which then get assigned to $a for the EmployeeID, $null for the User (we use $null here to simply ignore this token since you have already stated it was not of interest) and $b for the FileName. In PowerShell, this is known as multiple assignment.
To remove the extension from the $b token, as requested in your comment, regex is also not needed, you can use Path.GetFileNameWithoutExtension Method from System.IO.
$InStuff = #(
'111111_SMITH, JIM_END TLD 6-01-20 THR LEWISHS.pdf'
'222222_JONES, MIKE_G URS TO 7.25 2-28-19 SA COOPSHS.pdf'
)
foreach($i in $InStuff) {
$a, $null, $b = $i.Split('_')
[pscustomobject]#{
EmployeeID = $a
FileName = [System.IO.Path]::GetFileNameWithoutExtension($b)
}
}
Which results in:
EmployeeID FileName
---------- --------
111111 END TLD 6-01-20 THR LEWISHS
222222 G URS TO 7.25 2-28-19 SA COOPSHS

Related

PowerShell Regex get multiple substrings between 2 strings and write them to files with sequence numbers

Old thread
My question regards:
function GetStringBetweenTwoStrings($firstString, $secondString, $importPath){
#Get content from file
$file = Get-Content $importPath
#Regex pattern to compare two strings
$pattern = "$firstString(.*?)$secondString"
#Perform the opperation
$result = [regex]::Match($file,$pattern).Groups[1].Value
#Return result
return $result
}
GetStringBetweenTwoStrings -firstString "Lorem" -secondString "is" -importPath "C:\Temp\test.txt"
This is nice for only one -firstString and -secondString, but how to use this function to chronologically write multiple same strings in numbered TXT?
txt - file(with more sections of text):
Lorem
....
is
--> write to 001.txt
Lorem
....
is
--> write to 002.txt
and so forth....
And the structure of the section is preserved and is not in one line.
I hope someone can tell me that. Thanks.
The function you quote has several limitations (I've left feedback on the original answer), most notably only ever reporting one match.
Assuming an improved function named Select-StringBetween (see source code below), you can solve your problem as follows:
$index = #{ value = 0 }
Get-ChildItem C:\Temp\test.txt |
Select-StringBetween -Pattern 'Lorem', 'is' -Inclusive |
Set-Content -LiteralPath { '{0:000}.txt' -f ++$index.Value }
Select-StringBetween source code:
Note: The syntax is in part patterned after Select-String. After defining the function, run Select-StringBetween -? to see its syntax; the parameter names are hopefully self-explanatory.
function Select-StringBetween {
[CmdletBinding(DefaultParameterSetName='String')]
param(
[Parameter(Mandatory, Position=0)]
[ValidateCount(2, 2)]
[string[]] $Patterns,
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='File')]
[Alias('PSPath')]
[string] $LiteralPath,
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName='String')]
[string] $InputObject,
[switch] $Inclusive,
[switch] $SimpleMatch,
[switch] $Trim
)
process {
if ($LiteralPath) {
$InputObject = Get-Content -ErrorAction Stop -Raw -LiteralPath $LiteralPath
}
if ($Inclusive) {
$regex = '(?s)(?:{0}).*?(?:{1})' -f
($Patterns[0], [regex]::Escape($Patterns[0]))[$SimpleMatch.IsPresent],
($Patterns[1], [regex]::Escape($Patterns[1]))[$SimpleMatch.IsPresent]
}
else {
$regex = '(?s)(?<={0}).*?(?={1})' -f
($Patterns[0], [regex]::Escape($Patterns[0]))[$SimpleMatch.IsPresent],
($Patterns[1], [regex]::Escape($Patterns[1]))[$SimpleMatch.IsPresent]
}
if ($Trim) {
[regex]::Matches(
$InputObject,
$regex
).Value.Trim()
}
else {
[regex]::Matches(
$InputObject,
$regex
).Value
}
}
}
Note that there's also a pending feature request on GitHub to add this functionality directly to Select-String - see GitHub issue #15136

Version strings to "System.Version" too long (or short) in PowerShell

How can I force conversion to type System.Version in PowerShell, or more likely, better understand why I cannot arbitrarily assign number strings type System.Version?
We ingest some software updates in folders whose titles include version numbers. In trying to get reports on what the latest versions ingested are, I have been doing the following quick and dirty:
ForEach ($Folder in $(Get-ChildItem -Path $SoftwareDirectory -Directory))
{
$CurrentVersion = $Folder -Replace "[^0-9.]"
If ($CurrentVersion -ne $null)
{
If ([System.Version]$CurrentVersion -gt [System.Version]$MaxVersion)
{
$MaxVersion = $CurrentVersion
$MaxFolder = $Folder
}
}
}
This would be fed directory titles like the following,
foo-tools-1.12.file
bar-static-3.4.0.file
Most of the time, this is acceptable. However, when encountering some oddballs with longer numbers, like the following,
applet-4u331r364.file
In which case, System.Version refuses the resulting string as being too long.
Cannot convert value "4331364" to type "System.Version". Error: "Version string portion was too short or too long."
You need to ensure that your version strings have at least two components in order for a cast to [version] to succeed:
(
#(
'oo-tools-1.12.file'
'bar-static-3.4.0.file'
'applet-4u331r364.file'
) -replace '[^0-9.]'
).TrimEnd('.') -replace '^[^.]+$', '$&.0' | ForEach-Object { [version] $_ }
The above transforms 'applet-4u331r364.file' into '4331364.0', which works when cast to [version].
Note that you can avoid the need for .TrimEnd('.') if you exclude the filename extension to begin with: $Folder.BaseName -replace '[^0-9.]'
-replace '^[^.]+$', '$&.0' matches only strings that contain no . chars., in full, i.e. only those that don't already have at least two components; replacement expression $&.0 appends literal .0 to the matched string ($&).
Output (via Format-Table -AutoSize):
Major Minor Build Revision
----- ----- ----- --------
1 12 -1 -1
3 4 0 -1
4331364 0 -1 -1

How can i delete string in variable powershell?

I have a log file like this :
[2021/04/13 18:21:57.577+02:00][VERBOSE] Finished: 0 file(s), 5.23 GB; Average Speed:17.26 MB/s.
I just want to remove all string between the "," and "/s." I tried many times I can't do it correctly.
Can someone help me to do this on Powershell ?
If you do not only need to get the interesting part from the log line, but also need to be able to do math on the number ('5.23 GB') in your example, you need to do some more splitting:
foreach ($line in (Get-Content -Path 'TheFile.log')) {
$interestingPart = ($line -split ',')[-1].Trim()
$logSize, $logAverage = $interestingPart -split ';'
$size, $unit = $logSize -split '\s+'
# calculate the size from both the number ('5.23') and the unit ('GB')
$size = [double]::Parse($size) * "1$unit"
# now you have the number to do further math on
}

How to validate azure resource naming conventions using PowerShell

I want to check the name (for example azure vnet) provided in script to validate for azure vnet naming convention (Like it should not have any special character and length 2-64)
I am using below code but it is not working if string $name has special character in it.
It is working only for 0-9 and a-z.
$name = "zzz"
$name -cmatch "^[0-9a-z]*$"
Need a code to check a string which has for special character.
If it has special character it should return true.
Try :
$name = "hello#"
if($name -match '[^a-zA-Z0-9]')
{
Write-Host "special character found"
}
else
{
Write-Host "special character not found"
}
Try this one, if there is a special character in name, it will return true.
$name = "_"
$name -notmatch "[0-9a-zA-Z]"

Converting Unicode string to ASCII

I have strings containing characters which are not found in ASCII; such as á, é, í, ó, ú; and I need a function to convert them into something acceptable such as a, e, i, o, u. This is because I will be creating IIS web sites from those strings (i.e. I will be using them as domain names).
function Convert-DiacriticCharacters {
param(
[string]$inputString
)
[string]$formD = $inputString.Normalize(
[System.text.NormalizationForm]::FormD
)
$stringBuilder = new-object System.Text.StringBuilder
for ($i = 0; $i -lt $formD.Length; $i++){
$unicodeCategory = [System.Globalization.CharUnicodeInfo]::GetUnicodeCategory($formD[$i])
$nonSPacingMark = [System.Globalization.UnicodeCategory]::NonSpacingMark
if($unicodeCategory -ne $nonSPacingMark){
$stringBuilder.Append($formD[$i]) | out-null
}
}
$stringBuilder.ToString().Normalize([System.text.NormalizationForm]::FormC)
}
The resulting function will convert diacritics in the follwoing way:
PS C:\> Convert-DiacriticCharacters "Ångström"
Angstrom
PS C:\> Convert-DiacriticCharacters "Ó señor"
O senor
Copied from: http://cosmoskey.blogspot.nl/2009/09/powershell-function-convert.html
Taking this answer from a C#/.Net question it seems to work in PowerShell ported roughly like this:
function Remove-Diacritics
{
Param([string]$Text)
$chars = $Text.Normalize([System.Text.NormalizationForm]::FormD).GetEnumerator().Where{
[System.Char]::GetUnicodeCategory($_) -ne [System.Globalization.UnicodeCategory]::NonSpacingMark
}
(-join $chars).Normalize([System.Text.NormalizationForm]::FormC)
}
e.g.
PS C:\> Remove-Diacritics 'abcdeéfg'
abcdeefg

Resources