PowerShell - piped property not not working as I had hoped - powershell

I am a little new to PowerShell, so this is probably a basic question.
I have written a small one-liner to remove the first 97 lines from the top of each text file in a directory.
The script works in as far as removing the line, but the new file created at the end doesn't have the name I expected. Here is the script:
Get-ChildItem | ForEach-Object {Get-Content $_.PSPath | Select -Skip 97 | Set-Content "Edited-$_.PSChildName" }
The original file is called:
file.txt
What I expect the new file to be called is:
Edited-file.txt
The file actually comes out as:
Edited-file.txt.PSChildName
Any idea what I am doing wrong?

I think you want Set-Content "Edited-$($_.PSChildName)". The $() allows you to interpolate expressions into strings e.g. "abc$(2+2)" returns the string "abc4".

Related

How can I add a line break for every tilde found within the contents of several files found at a path?

I would like to use PowerShell to add a line break for every tilde it finds in a file.
The source could contain main .in files which contain tildes.
I have this script so far, and could benefit by some assistance in how to tweak it.
This will work for one file, but not for many:
(Get-Content -Path '.\amalgamatedack.in') |
ForEach-Object {$_.Replace('~', "~`r`n")} |
Set-Content -Path '.\amalgamatedack.in'
You can use Get-ChildItem to find all your .in files, then follow the same logic, just replace the input and output hardcoded file name for the absolute path of each file (.FullName property).
Your code could also benefit by using Get-Content -Raw, assuming these files are not very big and they fit in memory, reading the content as single multi-line string is always faster.
# If you need to search recursively for the files use `-Recurse`
Get-ChildItem path\to\sourcefolder -Filter *.in | ForEach-Object {
($_ | Get-Content -Raw).Replace('~', "~`r`n") |
Set-Content -Path $_.FullName
}

How to extract a value out of a file, and save it in a new file, using Powershell

I recently started using Powershell and I'm trying out some code.
I have a .cfg file with several rules of code. The code is written like this:
ad.name=1
ad.virtual=active
ad.set=none
ad.partition=78
Now I want to export the value of ad.partition, which is 78, to a new file. I don't want to export ad.partition or = but only the number 78.
So far I got this:
Get-Content -Path C:\file.cfg | Where-Object {$_ -like 'ad.partition=78'}
But then I -obviously- just get the variable and the value. Not sure how to continue...
I hope someone has a way of achieving what I want.
After saving the value in a new file, would it be possible to add spaces? For example, the value consists out of 9 digits, e.g. 123456789. The desired output result would be 123 456 789.
Use ConvertFrom-StringData cmdlet to create a hash table from your file, then simply index the key you are after:
$h=(Get-Content -Path C:\file.cfg | ConvertFrom-StringData)
$h.("ad.partition") -replace ('^(\d{1,3})(\d{1,3})?(\d{1,3})?','$1 $2 $3') > C:\out.cfg
You can use the Select-String cmdlet to capture your desired value using a regex. Then just pipe the result to the Out-File cmdlet. To get your desired output with spaces, you can use a simple format string:
"{0:### ### ###}" -f [int](Select-string 'ad\.partition=(.*)' -Path C:\file.cfg).Matches.Groups[1].Value |
Out-File C:\result.cfg

Batch File to Find and Replace in text file using whole word only?

I am writing a script which at one point has to check in a text file and remove certain strings. So far I have this:
powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"
The only problem is that that can find and replace but will not remove the line all together.
The second problem is that say I am removing the line that has Mark, it needs to not remove a line that has something like Markus.
I don't know if this is possible with the powershell interface?
Your current code will only replace foo with bar, this is what replace does.
Removing the whole line if it matches requires a different approach, almost backwards, as you can use notmatch to output any lines that do not match you filter - effectively removing them.
Also using regex word boundaries will then only match Mark but not Markus:
(Get-Content file.txt) | Where-Object {$_ -notmatch "\bMark\b"} | Set-Content file.txt

Set-content keeping busy my files

I'm trying to replace multiple strings for new ones, always in the same file.
This would be an example. This give me no problems.
(get-content modTags.bas) | %{$_ -replace "rng_origin.Offset(ColumnOffset:=1)", "rng_origin.Offset(ColumnOffset:=0)"} | set-content modTags.bas
But if I repeat this line in the script (in fact, i must do it like 20 times) I get the error that the file is currently in use.
I have tried to put (set-content) like in (get-content), but it seems it doesn't works for only allow parameters in the first command in the pipeline.
I already know how to "bypass" this error.
By typing all my replacements inline it works (or continue the code in a new line) like this.
(get-content modTags.bas) | %{$_ -replace "X","Y" `
-replace "A","B"} | set-content modTags.bas
So this is a question about why set-content keeps the file occupy for new query in the same script and how can it be avoided? With get-content it easy with the () solution, and I was kinda expecting something similar for set-content.
And second. Could you suggest any better alternative for replacing multiple strings for different ones and save it in the same file (not creating a file.new.txt file.old.txt or something like that)
Thanks!

Powershell - Getting a directory to output a file at a time

I'm super new at all of this so please excuse my lack of technical elegance and all around idiocy.
dir c:\Users\me\desktop\Test\*.txt | %{ $sourceFile = $_; get-content $_} | Out-File "$sourceFile.results"
How can I modify this command line so that instead of one file with the contents of all the text files I have a one to one ratio so that each output files represents the contents of each text file?
I realize that this object is ridiculous in terms of application but I'm conceptually trying to piece this together bit by bit so I can really understand.
P.S. What's with the %? Haha another ridiculous question, doesn't seem worth a separate post, what does it do?
dir | % { Out-File -FilePath "new_$($_.Name)" -InputObject (gc $_.FullName) }
only one pipeline needed. this command appends "new_" to the filename because I was using the same directory to write to. You can remove this if it's not needed.