Powershell - search for string, remove excess whitespace, print second field - powershell

I'm having a problem parsing some string data in powershell and need a little help. Basically I have an application command that doesn't output objects, rather string data.
a = is the item I'm searching for
b = is the actual ouput from the command
c = replaces all the excess whitespace with a single space
d = is supposed to take $c "hostOSVersion 8.0.2 7-Mode" and just print "8.0.2 7-Mode"
However, $d is not working it just prints the same value as $c. I'm a UNIX guy and this would be easy in one awk statement. If you know how to do this in one command that would be nice, or just tell me what's wrong with my $d syntax below.
$a = "hostOSVersion"
$b = "hostOSVersion 8.0.2 7-Mode"
$c = ($a -replace "\s+", " ").Split(" ")
$d = ($y -replace "$a ", "")

Well you might have to futz around with the exact pattern, but one way is with a regex:
$b = "hostOSVersion 8.0.2 7-Mode"
$b -match '(\d.*)'
$c = $matches[1]
If you really wanted to oneline it with -replace:
$($($b -replace $a, '') -replace '\s{2}', '').trim()

Your line
$c = ($a -replace "\s+", " ").Split(" ")
should reference the $b variable instead of $a
$c = ($b -replace "\s+", " ").Split(" ")
Then, you will notice the output of $d becomes
hostOSVersion
8.0.2
7-Mode
and a statement like $d[1..2] -join ' ' would produce 8.0.2 7-Mode

Related

Blank result for String concatenation in foreach

There might not be the best way but what is wrong with this code. Why do i get blank result from $str in the foreach loop, whereas if it try to concatenate individual cells i get the right result.
$csv = import-csv -Path "C:\Users\abc\csv4script\TEST.csv" -Header 'IPs'
$str = ''
$x = 1
foreach ($cell in $csv.){
if ($x -le 4000){
$str = $str + ", " + $cell.IPs
if ($x -eq 4000){
$x = 1}
$str = ''
}
$x = $x + 1
}
$str
# $str = $str + $csv[1].IPs + ", " + $csv[2].IPs
$str
It doesn't have a value because you misplaced a '}' character.
$x = 1}
Move it to after $str = ''
$x = 1
$str = ''}
Also as Thomas pointed out, remove the period after $csv variable in your foreach statement, it should be like: foreach($cell in $csv)
Also if you want to increment a value,
$x++ is quicker and easier to read than $x = $x + 1
Lastly, as you have it, if your list has more than 4000 IPs the $str variable will empty out.

How to cut specific characters in a string and save it to a new file?

I have a string, and I want to cut some characters and store it to a new file.
I tried this code, but it still error.
$a = ";Code=NB"
$b = $a -split "="
$b[1]
$Save = "[AGM]", "CR=JP", "LOC= $b[1]"| Out-File "C:\Users\Out.txt"
Try something like this:
$a = ";Code=NB"
$null, $b, $null = $a -split '=', 3
$b
$Save = "[AGM]", "CR=JP", "LOC= $b"| Out-File "C:\Users\Out.txt"
Something that would be easier to maintain would be this:
#Words to remove from string
$wordsToCut = "This","is"
#Phrase to remove words from
$phrase = "This is a test"
#Running through all words in words to remove
foreach ($word in $wordsToCut){
#Replace current word with nothing
$phrase = $phrase.Replace($word,"")
}
#Output end result
Write-Host $phrase
You would also use trim to remove any leading or trailing spaces. The above code outputs:
a test

Concatenate Arrays as String with PowerShell

i have two array ($a , $b) which holds the following strings:
$a
MSSQL11.SQLINST15
MSSQL12.SQLINST16
MSSQL12.SQLINST17
$b
2874
2884
2885
That i'm trying to concatenate to a new array ($c), as a strings with a comma sign in the middle:
$c
MSSQL11.SQLINST15,2874
MSSQL12.SQLINST16,2884
MSSQL12.SQLINST17,2885
Problem is, that using my current ps code:
$c = #($a + ',' + $b)
[string]::Concat($c)
$c
I'm getting a very strange output:
MSSQL11.SQLINST15
MSSQL12.SQLINST16
MSSQL12.SQLINST17
,
2887
2884
2885
At the end, i've use a powershell hashtable.
I like this way of doing it. Create a zip function to combine your two arrays into a single array of tuples.
Then it's just a matter of piping piece-wise over that tuple list our zip function gives us. Super convenient and reusable.
function Zip($a, $b) {
while ($a) {
$x, $a = $a
$y, $b = $b
[tuple]::Create($x, $y)
}
}
$c = zip $a $b |% {$_.item1 + [string]$_.item2}
Note you can choose where ya wanna to your [string] conversion (in the following, the last line of zip).
function Zip($a, $b) {
while ($a) {
$x, $a = $a
$y, $b = $b
[tuple]::Create([string]$x, $y)
}
}
$c = zip $a $b |% {$_.item1 + $_.item2}
Extra info: Looks like you're accidentally just combining the two arrays using a ",". But $a and $b are arrays, so what you actually want to do is combine the first element of $a with the first element of $b (aka $a[0] + [string]$b[0], and so on for each element. Why the [0]? Remember we almost always start counting at 0 in programming. So the second item of an array is actually [1].
Edit: Here is an example using a foreach loop.
```
foreach($item in $a) {
$i = $a.IndexOf($item)
$a[$i] + [string]$b[$i]
}
```
If for some reason $a has 10 things in it, and $b only has 2 things, it's gonna give you funny behavior. So be careful there. Please let me know if I can better clarify anything. Don't forget to experiment.

How do edit the last occurrence of a particular string in powershell

My text file contains G-Code with the code "G94" appearing 5 times at different line numbers.
G94
G94
G94
G94
G94
I need to change the last occurrence of "G94" to
G94
/M16
but I keep getting no edit at all.
I'm trying this:
$text = get-content C:\cncm\g94.txt
$i = 1
$replace = 5 #Replace the 5th match
ForEach ( $match in ($text | select-String "G94" -AllMatches).matches)
{
$index = $match.Index
if ( $i -eq $replace )
{
$text.Remove($index,"G94".length).Insert($index,"G94 n /M16")
}
$i++
}
What am I missing?
$text is an array of strings, how are you calling Remove() without getting an exception? First because Remove() only takes one parameter, second because you can't remove from a fixed length array.
I'm thinking:
$text = get-content C:\cncm\g94.txt
$fifthMatch = ($text | select-string "G94" -AllMatches)[4]
$line = $text[$fifthMatch.LineNumber]
$line = $line.Remove($fifthMatch.index,"G94".length).Insert($fifthMatch.index,"G94 `n /M16")
$text[$fifthMatch.LineNumber] = $line
$text | out-file c:\cncm\g942.txt
Use regexp with negative lookahead on a string that contains the entire file.
Replacing last occurrence in the entire file - (?s) DOTALL mode allows .* to span across new line characters:
$text = [IO.File]::ReadAllText('C:\cncm\g94.txt')
$text = $text -replace '(?s)G94(?!.*?G94)', "G94`n/M16"
Replacing last occurrence in every line - (?m) MULTILINE mode:
$text = [IO.File]::ReadAllText('C:\cncm\g94.txt')
$text = $text -replace '(?m)G94(?!.*?G94)', "G94`n/M16"

Echo string showing escaped characters

Is there a way to echo a string showing the escaped characters in powershell? I am looking for something similar to the repr function in python. I would like to use this for debugging.
For example:
>>$var="abc`ndef"
>>echo $var
Output:
abc
def
Desired output:
"abc`ndef"
or
abc`ndef
This will unescape the ` replacing it with a \
Hence the -replace at the end:
$var="abc`ndef"
$var = [System.Text.RegularExpressions.Regex]::Escape($var) -replace '\\','`'
echo $var
Output:
abc`ndef
I know this is not what you want, but will work fine :)
function Get-EscapedString([string] $String) {
$escape = #{
"`0"='`0';
"`a"='`a';
"`b"='`b';
"`f"='`f';
"`n"='`n';
"`r"='`r';
"`t"='`t';
"`v"='`v'
}
$str = $String
foreach ($char in $escape.Keys) {
$str = $str -replace $char, $escape[$char]
}
$str
}
Surround the string with single-quotes and the escape sequences won't be interpreted:
"abc`ndef"
outputs
abc
def
but
'abc`ndef'
outputs
abc`ndef