0

I have a Config file and I want to replace all the lines between two lines using powershell Here is my code:

 $HttpPath = "C:\Oracle\Middleware\Oracle_Home\user_projects\domains\my_domain\config\fmwconfig\components\OHS\ohs1\httpd.conf"
 $NewLine = 'Options -Indexes'
 $Pattern = '(?<=<Directory />).*?(?=</Directory>)'
(Get-Content -Path $HttpPath -Raw) | ForEach-Object {
  $_ -replace $Pattern,$NewLine
 } | Set-Content -Path $HttpPath

Here is text of config the file:

 <Directory />
 AllowOverride none
 Require all denied
 </Directory>

I want to replace two lines of "Hi" and "Hello" with one line "Options -Indexes". Result should look like:

<Directory />
Options -Indexes
</Directory>

This script works if the file content be like:

<Directory /> AllowOverride none Require all denied </Directory>

Then Output be like:

<Directory />Options -Indexes</Directory>

But as the content of file splits in separate lines, this does not works.

7
  • What does your existing code do? Commented Apr 1, 2020 at 10:43
  • If this is xml, it is better to treat it as such. Yet <Directory /> is a self-closed tag and </Directory> is a close tag... Anyways, you might try to use Get-Content -Raw to get the file as a single text [String] rather than an array of lines ([String[]]). Commented Apr 1, 2020 at 11:19
  • This script suppose to remove two lines between <Directory /> and </Directory> and replace it with "Options -Indexes". But now no changes get applied with the script. Commented Apr 1, 2020 at 11:38
  • <Directory /> is a start tag, and "/" here is a directory path. </Directory> is closing-tag for it. Commented Apr 1, 2020 at 11:40
  • This script applies the change if all the content present in one line. But does not work for multiple lines as mentioned in the problem statement. Commented Apr 1, 2020 at 11:46

1 Answer 1

0

You can do the following:

$Pattern = '(?s)(?<=<Directory />\r?\n).*?(?=</Directory>)'
$NewLine = "{0}{1}" -f 'Options -Indexes',[Environment]::NewLine
(Get-Content http.conf -raw) -replace $Pattern,$NewLine | Set-Content http.conf

Explanation:

Using the -Raw switch of Get-Content allows you to work with multiple lines without having to store previous line outputs. It reads the entire file as a single string instead of an array of strings.

The s modifier (used with syntax (?s)) is the single-line modifier. It allows the regex character . to match newline characters, which you will have since your target text is between two other lines.

The mechanism (?<=text) is a positive lookbehind assertion from the current position. It expects text to be behind the current position. \r?\n matches 0 or 1 carriage return and 1 newline. text will not be removed here.

The mechanism (?=text) is a positive lookahead assertion checking that text is ahead of the current position. text will not be removed here.

-f is the string format operator. This is not required, but it is a useful way to construct a string with programmable parts.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. This works. But the closing-tag is coming one step above with the new line added. How to shift that closing-tag to separate line?
That must mean [Environment]::NewLine is not working for you. You could replace it with "`r`n".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.