What is an equivalent of *Nix 'cut' command in Powershell?
Solution 1
You can read the contents of the file using Get-Content
, then pipe each line through ForEach-Object
, then use the split command on each line, taking the second item in the array as follows:
$filename = "sample.cfg"
Get-Content $filename | ForEach-Object {
$_.split(":")[1]
}
Output
300
2
10.0.0.9
1840
Update
I prefer the approach by @AnsgarWiechers, but if you really need specifically named values you could create a hashtable and replace the name with the value:
$configValues = @{
hour = "Time_Zone_Variance(Mins)"
min = "Alert_Interval(Mins)"
server = "Server"
port = "Port"
}
Get-Content $filename | ForEach-Object {
# Courtesy of Ansgar Wiechers
$key, $value = $_ -split ':', 2
foreach($configValuesKey in $($configValues.keys)) {
if ($configValues[$configValuesKey] -eq $key)
{
$configValues[$configValuesKey] = $value
}
}
}
write-host "`nAll Values:"
$configValues
write-host "`nIndividual value:"
$configValues.port
Output
All Values:
Name Value
---- -----
port 1840
min 2
server 10.0.0.9
hour 300
Individual value:
1840
Solution 2
How's this?
function cut {
param(
[Parameter(ValueFromPipeline=$True)] [string]$inputobject,
[string]$delimiter='\s+',
[string[]]$field
)
process {
if ($field -eq $null) { $inputobject -split $delimiter } else {
($inputobject -split $delimiter)[$field] }
}
}
PS C:\> 'hi:there' | cut -f 0 -d :
hi
PS C:\> 'hi:there' | cut -f 1 -d :
there
PS C:\> 'hi:there' | cut -f 0,1 -d :
hi
there
PS C:\> 'hi:::there' | cut -f 0 -d :+
hi
PS C:\> 'hi there' | cut
hi
there
Solution 3
I suppose you don't want to just split the lines, but actually create key/value pairs. That could be achieved like this:
$config = @{}
Get-Content 'C:\path\to\sample.cfg' | % {
$key, $value = $_ -split ':', 2
$config[$key] = $value
}
You could also use the ConvertFrom-StringData
cmdlet:
Get-Content 'C:\path\to\sample.cfg' | % {
ConvertFrom-StringData ($_ -replace ':','=')
}
The -replace
operation is necessary, because ConvertFrom-StringData
expects key and value to be separated by =
. If you could change the delimiter in the config file from :
to =
, you could use ConvertFrom-StringData $_
without replacement.
Solution 4
For a more succint syntax, this will also do the trick:
((Get-Content "your-file.txt") -Split ":")[1]
So the trick to use the -Split
method is to have a String
object returned by Get-Content
(alias cat
can also be used, actually), and from the resulting String[]
object you can use the brackets to extract the n
th item.
Note: Using
-Split
without parenthesis aroundGet-Content
won't work since-Split
is not a parameter name for that command... 🤷♂️
Related videos on Youtube
Comments
-
HamTheAstroChimp over 3 years
I have following content in a configuration file (sample.cfg),
Time_Zone_Variance(Mins):300 Alert_Interval(Mins):2 Server:10.0.0.9 Port:1840
I'm trying to store an each values after the
:
by usingsplit
in PowerShell. but i'm not able to produce require output.Can someone tell me how to use PowerShell
split
for the above problem ? -
Ansgar Wiechers almost 10 yearsFor individually named variables you could do something like
$configValues.Keys | % { New-Variable -Name $_ -Value $configValues[$_] }
. -
vt100 over 6 yearsIt is close to 'cut' - only new line characters should not be inserted. Input is one line, output is as many lines as number of fields you selected. +1 anyway.
-
js2010 over 6 yearsThe output is actually an array, but powershell displays it that way.
-
orion elenzil over 2 yearsgreat answers here. if you happen to be splitting on space instead of colon, and your data may have a variable number of spaces as a single delimiter, don't forget to collapse them via something like
($_ -replace ' *', ' ')
.