1

I am new to Powershell scripting and i have gone through the powershell tutorial to complete my current script requirement.

I am trying to add exclamatory mark to the line by matching the pattern. I am having similar test.default file as below

"/AgentSetup/__type__"

"/AgentSetup/__name__"

"/AgentSetup/preloadedKs"

"/AgentSetup/preloadedKMsArch"

"/AgentSetup/loadOnlyPreloadedKMs"

More lines like this in the file

So here i am trying add exclamatory mark to the starting of the line by matching for example if i search for "/AgentSetup/preloadedKs" = { REPLACE="" }, then in the file it should look like

"/AgentSetup/__type__"

"/AgentSetup/__name__"

"/AgentSetup/preloadedKs"

!"/AgentSetup/defaultAccount"

"/AgentSetup/preloadedKMsArch"

"/AgentSetup/loadOnlyPreloadedKMs"

I tried below commands to achieve this but not succeefull

$TEST = "C:\Asset\config.default"
$Pattern = "/AgentSetup/defaultAccount"
$var = "!" + (Select-String -Path $TEST -pattern $Pattern | Out-String)
$var
$var + (Get-Content $TEST -Raw) | Set-Content $TEST

The above commands is not just adding exclamatory mark but adding dublicate entry in the file like this:

!

test.default:103:"/AgentSetup/defaultAccount"

I have gone through powershell Add-Content and Select-String tutorial even I searched Get-Content. Please guide me to the right direction so i can achieve this it would be helpful.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Alex
  • 93
  • 1
  • 7
  • here's the steps i would use ... [1] read the file into a $Var [2] iterate thru that collection [3] match on the desired string [4] if no match, send string out to a NEW file with `Add-Content` [5] if match found, edit string & send to the same file – Lee_Dailey Feb 27 '19 at 12:27
  • Step (5) you mean to say concatenate currently reading concatenation will update if any success – Alex Feb 27 '19 at 12:31
  • edit means to change. [*grin*] if you choose to do that with concatenation, then it is still an edit. ///// good luck! – Lee_Dailey Feb 27 '19 at 12:44
  • 1
    replace `(Select-String -Path $TEST -pattern $Pattern | Out-String)` with `(Select-String -Path $TEST -pattern $Pattern).Line` – Mathias R. Jessen Feb 27 '19 at 15:09
  • Thanks Mathias for your kind suggestion and help – Alex Feb 27 '19 at 19:10

1 Answers1

1

There are two problems with your approach:

  • As Mathias R. Jessen suggests in a comment, instead of piping the Select-String call's output to Out-String[1], access the .Line property on the result, which contains the matched line only.

  • You're simply prepending the modified copy of the line of interest to your output, which means that the original, unmodified line remains part of the rewritten file.

I suggest using a different approach altogether, based on the -replace operator, which makes for a solution that is both more concise and faster:

(Get-Content $TEST) -replace '^"/AgentSetup/preloadedKs"$', '!$&' | Set-Content $TEST
  • ^ matches the start of each input string and $ the end, so that only lines that contain nothing but the search string are matched.

  • $& is a placeholder for what was matched, i.e. the original line in this case; for more about -replace and these placeholders, see this answer.

Note that this updates the line in its original position.

Enclosing the Get-Content call in (...) ensures that the file is read in full up front, which enables writing back to the same file with Set-Content in the same pipeline; while this is convenient, it bears a slight risk of data loss, if writing back to the file is interrupted.


[1] The purpose of Out-String is to create string representations of objects as they would print to the console, which is generally not suitable for programmatic processing; even using .ToString() on the match-info objects (or placing them inside "...") won't work as intended in this case, because the resulting representation includes the input filename too.

mklement0
  • 382,024
  • 64
  • 607
  • 775