My string is:
$dst = "Folder_1\SubFolder_2\3\4\5"
My goal is to have:
$dst_OK = "SubFolder_2\3\4\5"
I tried use split function like this:
$dst_OK = $dst.split("\")[0]
but the result is Folder_1 only.
You could use the following regex to remove the left side of the string:
$dst_OK = $dst -replace '^.*?\\'
However, since it looks like you are dealing with a path, you may consider to using builtin function within the System.IO.Path namespace.
You can do it with this snippet:
$first, $rest = "Folder_1\SubFolder_2\3\4\5" -split '\\'
$rest = $rest -join '\'
Other solution :
($dst -split "\\", 2)[1]
Solution 2
$dst.Substring($dst.IndexOf('\')+1)
Related
I'm looking for the correct syntax to add some (") between my variable.
I need something like that :
"firstname","lastname","email","",""
Here is the first script I have :
foreach($line in Get-Content .\extract.csv)
{ $firstname = $line.split(';')[0]
$lastname = $line.split(';')[1]
$email = $line.split(';')[2]
$newLine = "$firstname - $lastname - $email"
echo $newLine }
I'm really new in scripting and I'm a bit lost with all these (') (")
My second question is : I need to extract my data only from the second row and ignore the first one, can you help me for this too ?
Thanks !
Have you try escaping your " and ' ?
In powershell you can use backtick ` (AltGr + 7) or doubling the char to do so :
Example :
Write-Host(" `" ")
Write-Host(" "" ")
Please add more code if this doesn't solve you issue !
I have a text file which is comprised of only one line. I have had much trouble with splitting the file into a specific number of characters, then adding a string in front of each chunk of characters.
With a multi-line file, I can add characters to each line very easily using
Get-Content -Path $path | foreach-object {$string + $_} | out-file $output but it is much more complicated with a file with only one line.
For example, if I had a file with these random characters,
(******************************************) and i wanted to add a string to the start of every 10 chars, then it would look like this, (examplestring**********examplestring**********examplestring**********) and so on. I have researched everywhere but I have just managed to add the chars to the end of each chunk of characters.
Does anyone have a way of doing this? Preferably using streamreader and writer as get-content may not work for very large files. Thanks.
Hmm, there are some dynamic parameters applicable to file-system get-content and set-content commands that are close to what you are asking for. For example, if test.txt contains a number of * characters, you might interleave every four * with two + characters with something like this:
get-content .\test.txt -Delimiter "****" | % { "++$_" } | Set-Content test2.txt -NoNewline
I don't know how close that is to a match for what you want, but it's probably useful to know that some of these provider-specific parameters, like '-Delimiter' aren't obvious. See https://technet.microsoft.com/en-us/library/hh847764.aspx under the heading 'splitting large files'.
Alternatively, here's a quick function that reads length-delimited strings from a file.
Set-StrictMode -Version latest
function read-characters( $path, [int]$charCount ) {
begin {
$buffer = [char[]]::new($charCount)
$path = Join-Path $pwd $path
[System.IO.StreamReader]$stream = [System.IO.File]::OpenText($path)
try {
while (!$stream.EndOfStream) {
$len = $stream.ReadBlock($buffer,0,$charCount);
if ($len) {Write-Output ([string]::new($buffer,0,$len))}
}
} catch {
Write-Error -Exception $error[0]
} finally {
[void]$stream.Close()
}
}
}
read-characters .\test.txt -charCount 10 |
% {"+$_"} |
write-host -NoNewline
It could use some parameter checking, but should get you started...
With a manageable file size, you might want to try something like this:
$directory = "C:\\"
$inputFile = "test.txt"
$reader = new-object System.IO.StreamReader("{0}{1}" -f ($directory, $inputFile))
# prefix string of each line
$startString = "examplestring"
# how many chars to put on each line
$range = 10
$outputLine = ""
$line = $reader.ReadLine()
$i = 0
while ($i -lt $line.length) {
$outputLine += $($startString + $line.Substring($i, [math]::min($range, ($line.length - $i))))
$i += $range
}
$reader.Close()
write-output $outputLine
Basically it's using substring to cut out each chunk, prefixing the chumk with given string, and appending to the result variable.
Sample input:
==========================
Sample output:
examplestring==========examplestring==========examplestring======
I want to get "localhost" (or whatever text) inside this string:
XML-Execute-Result: <host>localhost</host>
I want a general method, like a way to reuse an expression value
(like with sed in linux)
sed 's/*[0-9]$/\$&/'
Thank you very much for any reply
$text = "XML-Execute-Result: <host>localhost</host>"
if ($text -match "\<host\>(?<host>.*?)\</host\>")
{
$myhost = $matches.host
}
PS> if ($text -match "<host>(.*?)</host>") {$matches[1]}
localhost
Whatever you want to call it, I'm trying to figure out a way to take the contents of an existing string and evaluate them as a double-quoted string. For example, if I create the following strings:
$string = 'The $animal says "meow"'
$animal = 'cat'
Then, Write-Host $string would produce The $animal says "meow". How can I have $string re-evaluated, to output (or assign to a new variable) The cat says "meow"?
How annoying...the limitations on comments makes it very difficult (if it's even possible) to include code with backticks. Here's an unmangled version of the last two comments I made in response to zdan below:
----------
Actually, after thinking about it, I realized that it's not reasonable to expect The $animal says "meow" to be interpolated without escaping the double quotes, because if it were a double-quoted string to begin with, the evaluation would break if the double quotes weren't escaped. So I suppose the answer would be that it's a two step process:
$newstring = $string -replace '"', '`"'
iex "`"$string`""
One final comment for posterity: I experimented with ways of getting that all on one line, and almost anything that you'd think works breaks once you feed it to iex, but this one works:
iex ('"' + ($string -replace '"', '`"') + '"')
Probably the simplest way is
$ExecutionContext.InvokeCommand.ExpandString($var)
You could use Invoke-Expression to have your string reparsed - something like this:
$string = 'The $animal says `"meow`"'
$animal = 'cat'
Invoke-Expression "Write-Host `"$string`""
Note how you have to escape the double quotes (using a backtick) inside your string to avoid confusing the parser. This includes any double quotes in the original string.
Also note that the first command should be a command, if you need to use the resulting string, just pipe the output using write-output and assign that to a variable you can use later:
$result = Invoke-Expression "write-output `"$string`""
As noted in your comments, if you can't modify the creation of the string to escape the double quotes, you will have to do this yourself. You can also wrap this in a function to make it look a little clearer:
function Invoke-String($str) {
$escapedString = $str -replace '"', '`"'
Invoke-Expression "Write-Output `"$escapedString`""
}
So now it would look like this:
# ~> $string = 'The $animal says "meow"'
# ~> $animal = 'cat'
# ~> Invoke-String $string
The cat says "meow"
You can use the -f operator. This is the same as calling [String]::Format as far as I can determine.
PS C:\> $string = 'The {0} says "meow"'
PS C:\> $animal = 'cat'
PS C:\> Write-Host ($string -f $animal)
The cat says "meow"
This avoids the pitfalls associated with quote stripping (faced by ExpandString and Invoke-Expression) and arbitrary code execution (faced by Invoke-Expression).
I've tested that it is supported in version 2 and up; I am not completely certain it's present in PowerShell 1.
Edit: It turns out that string interpolation behavior is different depending on the version of PowerShell. I wrote a better version of the xs (Expand-String) cmdlet with unit tests to deal with that behavior over here on GitHub.
This solution is inspired by this answer about shortening calls to object methods while retaining context. You can put the following function in a utility module somewhere, and it still works when you call it from another module:
function xs
{
[CmdletBinding()]
param
(
# The string containing variables that will be expanded.
[parameter(ValueFromPipeline=$true,
Position=0,
Mandatory=$true)]
[string]
$String
)
process
{
$escapedString = $String -replace '"','`"'
$code = "`$ExecutionContext.InvokeCommand.ExpandString(`"$escapedString`")"
[scriptblock]::create($code)
}
}
Then when you need to do delayed variable expansion, you use it like this:
$MyString = 'The $animal says $sound.'
...
$animal = 'fox'
...
$sound = 'simper'
&($MyString | xs)
&(xs $MyString)
PS> The fox says simper.
PS> The fox says simper.
$animal and $sound aren't expanded until the last two lines. This allows you to set up a $MyString up front and delay expansion until the variables have the values you want.
Invoke-Expression "`"$string`""
I have a string
$string = "Active Directory"
and I want to make another string
Active_Directory_Results.txt
I would like to just do
$otherstring = "$string.Replace(" ","_")_Results.txt"
but that doesn't work out. What would be the correct way to pull this off?
You should not use invoke-expression for that. The original answer is good:
$otherstring = $string.Replace(" ","_") + "_Results.txt"
But really, you can just use a $(subexpression):
$otherstring = "$($string.Replace(" ","_"))_Results.txt"
The $() tells PowerShell to evaluate that BEFORE defining the string.
As an alternative, you can also use string formatting:
$otherstring = "{0}_Results.txt" -f $string.Replace(" ","_")
Proving once again that with scripting languages, there's always more than one right way ...
I'm not on my windows machine right now, but how does $otherstring = $string.Replace(" ","_") + "_Results.txt" work?
Check the invoke-expression command. It allows you to execute code in a string.
Like:
PS> $command = '$otherstring = $string.Replace(" ","_") + "_Results.txt"'
PS> Invoke-Expression $command