Replace strings in text files with string literals and file names in powershell - string

My google-fu has failed me, so I'd love to get some help with this issue. I have a directory full of markup files (extension .xft). I need to modify these files by adding string literals and the filename (without the file extension) to each file.
For example, I currently have:
<headerTag>
<otherTag>Some text here </otherTag>
<finalTag> More text </finalTag>
What I need to end up with is:
<modifiedHeaderTag>
<secondTag> filenameGoesHere </secondTag>
<otherTag>Some text here </otherTag>
<finalTag> More text </finalTag>
So in this example,
"<modifiedHeaderTag>
<secondTag>"
would be my first string literal (this is a constant that gets inserted into each file in the same place),
filenameGoesHere
would be the variable string (the name of each file) and,
"</secondTag>"
would be my second constant string literal.
I was able to successfully replace text using:
(Get-Content *.xft).Replace("<headerTag>", "<modifiedHeaderTag>")
However, when I tried
(Get-Content *.xft).Replace("<headerTag>", "<modifiedHeaderTag> `n
<secondTag> $($_.Name) </secondTag>")
I just got an error message. Replacing $($_.Name) with ${$_.Name) also had no effect.
I've tried other things, but this method was the closest that I had gotten to success. I would appreciate any help that I can get. It's probably simple and I'm just not seeing something due to inexperience with Powershell, so a helping hand would be great.
If the above isn't clear enough, I'd be happy to provide more info, just let me know. Thanks everyone!

Here's my approach, assuming you have all of the XFT's in one folder and you want to write the updates back to the same file:
$path = "C:\XFTs_to_Modify"
$xfts = Get-ChildItem $path -Include "*.xft"
foreach ($xft in $xfts) {
$replace = "<modifiedHeaderTag>
<secondTag> $($xft.Name) </secondTag>"
(Get-Content *.xft).Replace("<headerTag>", $replace) | Set-Content $xft.FullName -Force
}

Related

Strange characters found in XML file and PowerShell output after exporting from Excel: ​

I have an XML file that I'm trying to read with PowerShell. However when I read it, the output of some of the XML objects have the following characters in them: ​
I simply downloaded an XML file I needed from a third-party, which opens in Excel. Then I grab the columns I need and paste them into a new Excel Workbook. Then I map the fields with an XML Schema and then export it as an XML file, which I then use for scripting.
In the Excel spreadsheet my data looks clean, but then when I export it and run the PS script, these strange characters appear in the output. The characters even appear in the actual XML file after exporting. What am I doing wrong?
I tried using -Encoding UTF8, but I'm relatively new to PowerShell and am not sure how to appropriately apply it to my script. Appreciate any help!
PowerShell
$xmlpath = 'Path\To\The\File.xml'
[xml]$xmldata = (Get-Content $xmlpath)
$xmldata.applications.application.name
Example of Output
​ABC_DEF_GHI​.com​​
​JKL_MNO_PQRS​.com​
TUV_WXY_Z.com
AB_CD_EF_GH​.com
This is a prime example of why you shouldn't use the idiom [xml]$xmldata = (Get-Content $xmlpath) - as convenient as it is.[1] The problem is indeed one of character encoding: your file is UTF-8-encoded, but Windows PowerShell's Get-Content cmdlet interprets it as ANSI-encoded in the absence of a BOM - this answer explains the encoding part in detail.Thanks, choroba.
Instead, to ensure that the XML file's character encoding is interpreted correctly, use the following:
# Note: If you know that $xmlPath contains a *full*, native path,
# you don't need the Convert-Path call.
($xmlData = [xml]::new()).Load((Convert-Path -LiteralPath $xmlPath))
This delegates interpretation of the character encoding to the System.Xml.XmlDocument.Load .NET API method, which not only assumes the proper default for XML (UTF-8), but also respects any explicit encoding specification as part of the XML declaration, if present (e.g., <?xml version="1.0" encoding="iso-8859-1"?>)
See also:
the bottom section of this answer for background information.
GitHub proposal #14505, which proposes introducing a New-Xml cmdlet that robustly parses XML files.
[1] If you happen to know the encoding of the input file ahead of time, you can get away with using Get-Content's -Encoding parameter in your original approach ([xml]$xmldata = (Get-Content -Encoding utf8 $xmlpath), but the .Load()-based approach is much more robust.

PowerShell trying to convert to an integer instead of a string

My problem is that PowerShell wants to convert "=" into an integer, when trying to use it to make a new string. I made sure that my resulting variable would also be a string. Here's my task:
I have a little Excel table like this:
___________|VLANID1|VLANID2|VLANID3|
SwitchName1| 1-7| 12-16| 8-11| ← Ports 1-7 of Switch1 are configure for VLAN1...
SwitchName2| 1-7| 12-16| 8-11|
Out of this table I want to save each port in an .ini file with the VLAN it is configured too, aka:
[SwitchName1]
1=VLANID1
2=VLANID3
...
And here's my code which I loop until there are no ports, and then no more switches.
$split = $global:Ports -split("-") #$Ports is the Value with the saved excel cell (7-11)
$split[0]..$split[1] | ForEach-Object {
$vlan = $global:Switches.Cells.Item(1, $global:SSpallte).Text
[string]$inistring = "`n" + $_ + "=" + $vlan #<- Here it tries to convert "=" into integer
Add-Content -Path $global:portsini -Value $inistring
}
I even tried converting every variable which I use to make $inistring to a string before, it still doesn't work. Also, both $_ and $vlan have a Value and are not $null.
The Error states that "=" cannot be converted into the type "System.Int32".
So, im not quite sure what the problem was, but my way to solve it was to restart my environment. I am programming in the PowerShell ISE which I have sometimes seen "caching" variables. This restart of the ISE made the program work again.
And no, I didn't change anything beforehand.
In the end I'm happy that my problem is no more, but I'm still wondering why the error got triggered by the "=".

Find and replace a specific string within a specific file type located in wildcard path

Problem:
Update a specific string within numerous configuration files that are found within the subfolders of a partial path using PowerShell.
Expanded Details:
I have multiple configuration files that need a specific string to be updated; however, I do not know the name of these files and must begin my search from a partial path. I must scan each file for the specific string. Then I must replace the old string with the new string, but I must make sure it saves the file with its original name and in the same location it was found. I must also be able to display the results of the script (number of files affected and their names/path). Lastly, this must all be done in PowerShell.
So far I have come up with the following on my own:
$old = "string1"
$new = "string2"
$configs = Get-ChildItem -Path C:\*\foldername\*.config -Recurse
$configs | %{(Get-Content $_) -Replace $old, $new | Set-Content $_FullName
When I run this, something seems to happen.
If the files are open, they will tell me that they were modified by another program.
However, nothing seems to have changed.
I have attempted various modifications of the below code as well. To my dismay, it only seems to be opening and saving each file rather than actually making the change I want to happen.
$configFiles = GCI -Path C:\*\Somefolder\*.config -Recurse
foreach ($config in $configFiles) {
(GC $config.PSPath) | ForEach-Object {
$_ -Replace "oldString", "newString"
} | Set-Content $config.PSPath)
}
To further exasperate the issue, all of my attempts to perform a simple search against the specified string seems to be posing me issues as well.
Discussing with several others, and based on what have learned via SO... the following code SHOULD return results:
GCI -Path C:\*\Somefolder\*.config -Recurse |
Select-String -Pattern "string" |
Select Name
However, nothing seems to happen. I do not know if I am missing something or if the code itself is wrong...
Some questions I have researched and tried that are similar can be found at the below links:
UPDATE:
It is possible that I am being thwarted by special characters such as
+ and /. For example, my string might be: "s+r/ng"
I have applied the escape character that PowerShell says to use, but it seems this is not helping either.
Replacing a text at specified line number of a file using powershell
Find and replacing strings in multiple files
PowerShell Script to Find and Replace for all Files with a Specific Extension
Powershell to replace text in multiple files stored in many folders
I will continue my research and continue making modifications. I'll be sure to notate anything that get's me to my goal or even a step closer. Thank you all in advance.

Replacing string but duplicate part of string

I have several batch files i need to alter.
looping through the files and replacing works fine.
I just cant figure out how to have a single line like
net use w: \\someserver\someshare
replaced by two lines
net use w: /delete /yes
net use w: \\someotherserver\someshare
is this at all possible with replace and regular expressions?
Or do i have to store the driveletter in a variable to accomplish this?
thanks,
Yes, that is possible with -replace:
$yourFilePath = 'PATH_TO_YOUR_FILE'
$content = Get-Content $yourFilePath
$content -replace '^net use (\w): .*', "net use `$1: /delete /yes `n`$0" | Set-Content $yourFilePath
The script adds the desired line to your file and uses the particualr drive, but doesn't check, whether the line (net use drive: /delete /yes) already exist.

replace string if you dont' know rest of string in PowerShell

Please help. Trying to figure out how to replace a string in PowerShell, but don't know the rest of the string. I have this:
(Get-Content $file) -replace[regex]::Escape('file='*''),('file='+$_.BaseName) | Set-Content $file
I don't know what comes after file=
I tried my code, but it replaces it multiple times instead of just once.
So trying to replace file=* with filename=$_.BaseName.
Thanks for looking.
Just an FYI for anyone using the latest version of PowerShell Community Extensions (http://pscx.codeplex.com), there is a new command called Edit-File that handles this sort of thing nicely (works hard to preserve the file's original encoding):
Get-Item test.txt | Foreach {$bn=$_.BaseName; $_} |
Edit-File -Pattern '(file=).*' -Replace "`${1}$bn"
In theory I shouldn't need the Foreach stage but it seems I've found a limitation in how -PipelineVariable does not work with parameters that aren't pipeline bound. Hmm, add that to the Pscx backlog.

Resources