6

I want to search and replace a string in an xml file using PowerShell. I tried this:

(gc d:\test.xml).replace('1234','xxxx')|sc d:\test.xml

This works fine for my test.xml file. The content of my test.xml file is:

uehjduehduhfeuf xxxxxxxx hallo "1234"

But that file is only for testing. I want to edit a server.xml form my tomcat server in this way and if I'm using exactly the same command mentioned obove I get this error message:

Method invocation failed because [System.Object[]] doesn't contain a method named 'replace'.

Does anybody know what's the problem?

4 Answers 4

7

You can also use [System.IO.File]::ReadAllText($filename) to get a single string out of a file, with all newlines and other symbols.

[System.IO.File]::ReadAllText("d:\test.xml").replace('1234','xxxx')|sc d:\test.xml
Sign up to request clarification or add additional context in comments.

3 Comments

If an answer helps you, please click a "tick" to the left of an answer that you want to mark as "the" answer. Please do that in all of your questions that have been correctly answered. This help both you and the entire Stack Overflow community.
You clicked an "upvote" (an arrow above the votes number), the "accept" (the green outlined tick below the downvote arrow) is different. Both can be used together. Also I've visited your profile and found that all your questions don't have an accepted answer, while two don't have any answers, two have answers you've marked as "thanks" (barring this one). So it's possible that you are unaware of what means what in here.
Thanks for this hints. I checked and changed it.
6

When you store the output of the Get-Content cmdlet in a variable, the data is stored as an array of type Object (i.e. Object[]) with one element for each line in the source file. Here's from the documentation:

When Get-Content reads a text file and stashes the contents in a variable, the data is stored as an array, with each line in the file (determined by the presence of a carriage return-linefeed character) representing a single item in the array.

When you put parenthesis around an expression, PowerShell creates a temporary variable, which in the case of Get-Content ends up being of type Object[].

In order to replace text from the source file, you need to iterate through the array and manipulate each line separately:

gc d:\test.xml | foreach { $_ -replace "1234", "xxxx" } | sc d:\test.xml

Or you can invoke the .NET BCL directly, as @Vesper pointed out.

Comments

1

Get-Content will give you an array of strings try using the raw switch like so:

(gc d:\test.xml -raw).replace('1234','xxxx')|sc d:\test.xml

4 Comments

Unfortunately this caused another error: Get-Content : A parameter cannot be found that matches parameter name 'raw'.
I think the raw flag was added in Powershell v3
@DaveSexton I don't see -raw as available in Get-Content even in Powershell 5.0.
It is in Microsoft documentation - see: technet.microsoft.com/en-us/library/hh847788(v=wps.620).aspx
1

Thank you for the explanation @Enrico Campidoglio!

In addition to your answer, some characters (such as PIPE in my case) will need to be escaped:

(gc d:\test.xml -raw).replace('\|',',')|sc d:\test.xml

I would have added this as a comment but I can't yet...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.