• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1181
  • Last Modified:

Powershell regex

Hello,

I'm trying to understand regular expressions in powershell, but seem to be having a hard time. I have a CSV file and I need to extract a value (IP address) from one of the columns. The column looks like this:

kdajfakldjfa.en.jlkjdaflsa.com.us.[192.168.4.0]dafldsj.com.us.ldaskjfkdsj
kdajfakldjfa.en.jlkjdaflsa.com.us.[192.168.5.0]dafldsj.com.us.ldaskjfkdsj
kdajfakldjfa.en.jlkjdaflsa.com.us.[192.168.6.0]dafldsj.com.us.ldaskjfkdsj
kdajfakldjfa.en.jlkjdaflsa.com.us.[192.168.7.0]dafldsj.com.us.ldaskjfkdsj

Obviously IP address are gonna differ so my regex filter would say find the first "[" and extract everything inside until you find the closing bracket "]"

I've tried doing this, but not getting me anywhere

$ips = import-csv c:\myfile.csv
foreach ($line in $lines){
     $line = regex::($line,"^\]")
}

can't seem to figure out how to say "extract everything until you find the next bracket"
0
bndit
Asked:
bndit
  • 4
  • 3
  • 3
  • +1
1 Solution
 
cantorisCommented:
How's about:

   $line -match "\[(.+)\]"
   $ip = $matches[0]
0
 
cantorisCommented:
Sorry, make that  $matches[1]
0
 
cantorisCommented:
Sorry, it's late...

Or better still,
   If ($line -match "\[(.+)\]") {$ip = $matches[1]}

(Because the -match line I put in my first answer returns a True or False.  If it's True, use matches[1] to get the first matched string - ie the IP.  I don't know if you need to handle a possible False condition.  If you don't need a test at all because the IP is definitely there, just do something like   $result = $line -match "\[(.+)\]"  to capture the boolean result of the regular expression match  and then get the   matches[1]  on the next line.)

In your original script, did you mean to say $lines = import-csv c:\myfile.csv  ?  As otherwise, $lines does not exist.
0
A Cyber Security RX to Protect Your Organization

Join us on December 13th for a webinar to learn how medical providers can defend against malware with a cyber security "Rx" that supports a healthy technology adoption plan for every healthcare organization.

 
QlemoC++ DeveloperCommented:
Explanation: -match works in the way that it applies the right-hand RegExp against the left-hand value. Anything grouped (in parens) in the RegExp will result into an own group in the $matches array, with $matches[0] being the whole string.
The RegExp used will catch all contents between the first and the last (!) square bracket - default mode for RegExp is "lazy", which means the widest fit. You will need to make sure you do not have more than one square bracket'd value per line in your CSV file, but I reckon that is ok.
0
 
bnditAuthor Commented:
Ok, so that works...now I'm trying to send the output to a text file but it's lumping everything together as opposed to placing each IP address on its own line such as:

192.168.0.2
192.168.0.3

my current output:

192.168.0.2192.168.0.3
$lines = Import-Csv C:\file.csv
$ips = @()
foreach($line in $lines){
	
	
	 If ($line -match "\[(.+)\]") {$ips += $matches[1]}
}
$ips | Set-Content c:\cleanips.txt

Open in new window

0
 
bnditAuthor Commented:
Nevermind...it was a simple fix

If ($line -match "\[(.+)\]") {$ips += $matches[1] + "`\n"}
0
 
bnditAuthor Commented:
Spoke too soon.....it's "`n" instead of "`\n" and it only works when I run the script from within the PowerGui editor and send the output to the screen...but not when the output is sent to a text file...any ideas why?
0
 
bnditAuthor Commented:
Strange....added "`r`n" and it worked when I sent the output to a text file.....why would `n not work?
0
 
Terry WoodsIT GuruCommented:
Windows uses a line feed and carriage return at the end of each line, whereas linux systems just use a carriage return - sometimes there is compatibility between the 2 methods, but it often causes trouble.
0
 
QlemoC++ DeveloperCommented:
Strange, because you should not need to insert newline and/or carriage return when outputting array content. It works for me in the plain PowerShell prompt:
$ip = @()
$ip += "192.168.1.1"
$ip += "192.168.1.2"
$ip | set-content c:\cleanips.txt

Open in new window

But the "proper" way to process and output is
get-content C:\file.csv | % {if ($_ -match "\[(.+)\]") {$matches[1]} } | Set-Content c:\cleanips.txt

Open in new window

In particular I cannot see anything CSV like in the snippet you provided, and so there is no need to use the import-csv; get-content will do better here, as it just reads the complete line as a single string.
0
 
QlemoC++ DeveloperCommented:
My help was not worth some points?
0

Featured Post

What Security Threats Are We Predicting for 2018?

Cryptocurrency, IoT botnets, MFA, and more! Hackers are already planning their next big attacks for 2018. Learn what you might face, and how to defend against it with our 2018 security predictions.

  • 4
  • 3
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now