How do I delete a line from a text file in powershell? - powershell

Suddenly I have the urge to finally get into powershell. Right now I have a way to import a text file, create a text file, and add to a file, but is there a way to delete elements from a file? For example if I have a text file:
test.txt
Quick
Brown
Fox
I can import the file with
$textFile = Get-Content -Path ".\test.txt"
and I can print each element and add them to a new file with
foreach($line in $textFile)
{
Write-Host $line
Add-Content -Path ".\output.txt" -Value $line
}
But how can I delete or remove an element (a line) from the test.txt file? I googled for a solution but I only get results for conditions in which someone wants to delete a blank line, deleting the entire file, or how to do it in C#. I thought it would be as intuitive as the previous commands..
Thanks for the feedback!

Take this thread as an example, it deletes lines by reserving lines which doesn't contains specific content.
You can do the same thing by reserving the line you don't want to delete.
Get-Content .\text.txt | Where-Object {$_ -notmatch 'the-word-in-specific-line'} | Set-Content out.txt
So, if you want to delete the line containing the string Brown:
Get-Content .\test.txt | Where-Object {$_ -notmatch 'Brown'} | Set-Content out.txt

Related

How to replace a newline at the start of a txt file with powershell

I have tried a lot, but I cannot seem to replace the new line at the start of a txt file.
So my txt file looks like this:
I just want to remove the first newline character, but everything I try does not work:
Replace ``n`r, replace \n\r or any combination of these.
Try
(Get-Content -Path 'YourFile.txt' -Raw).TrimStart() | Set-Content -Path 'YourFile.txt' -Force
Or
(Get-Content -Path 'YourFile.txt' -Raw) -replace '^\s+' | Set-Content -Path 'YourFile.txt' -Force
Explanation:
The above removes all whitespace (tabs, spaces, newlines) from the top of the text, as it is impossible to see from the image if other whitespace characters are in that line or not.
If you are sure there is just the one newline, in your case \r\n won't work, because the file uses Unix newlines (\n only).
Better is to replace using ^\r?\n. The ^ anchors at the beginning of the text. The ? reads zero or one on the CR character \r
This would replace all blank lines. The parentheses make sure the first command finishes first if you're writing to the same file.
(get-content file.txt) | where { $_ } | set-content file.txt
Or this way, the filename goes first.
set-content file.txt (get-content file.txt).where{$_}
A different approach
( Get-Content -Tail ( ( Get-Content testfile1 ).count-1 ) testfile1 ) | Set-Content testfile1
Count the number of lines in the file and then take one off the total. Use that to tail the file and write the output back to the file.
If you are certain that there will be an empty line (or you want to ignore it) you can use Skip.
Get-Content -Path 'YourFile.txt' | select -Skip 1 | Set-Content -Path 'YourFile.txt' -Force

Powershell script to run multiple input text files

I'm trying to remove spaces from input text file through PowerShell script.
I have hundreds if thousands of text files where I have to remove the spaces. I wrote the code to remove spaces. It is working fine for one text file but I want to execute more than one file .
gc C:\test\3.txt | where {$_ -ne ""} > C:\test\out.txt
In the above example I have more input files like 4.txt , 5.txt , 6.txt etc. I want to execute all the files in one shot and remove the spaces and write the 4out.txt, 5out.txt, 6out.txt, etc. to another folder.
It should just be a case of looping through your files and running the same line you already have.
Add some try-catch if you'd like to be safe.
$InputFiles = Get-ChildItem 'C:\test\'
$OutputPath = 'C:\test\out\'
ForEach($File in $InputFiles) {
Get-Content $File |
Where-Object {$_ -ne ''} |
Out-File (Join-Path -Path $OutputPath -ChildPath $File.Name)
}

How to change a character in multiple .txt-files and save/ overwrite the existing file in Powershell

i'm really new to Powershell (2 days) and i am not good yet. :(
My Question ist:
How to change a character in multiple .txt-files and save/ overwrite the existing file in Powershell
My goal is to Copy multiple RAW-Files in a new folder, change the file-name from .tsv to .txt and at least change one character in these files from % to percent.
What i've got so far:
The first two steps are working, but i'm losing my mind with the third step (the replacement).
Copy-Item -Path "C:\Users\user\Desktop\RAW\*.tsv" -Destination "C:\Users\user\Desktop\TXT" -Recurse
Set-Location "C:\Users\User\Desktop\TXT"
Get-ChildItem *.tsv | Rename-Item -NewName { $_.Name -replace '.tsv','.txt' }
This works fine for me and now i am not able to get further ...
I am able to replace the "%" in one specific file, and save it in a new file, but this doesn't work for a batch processing with changing file-names.
$file = "A.txt"
Get-Content $file | Foreach {$_ -replace "%", "percent"} | Set-Content A_1.txt
It would be perfect, if "$file = "A.txt"" would be "all the files in this path with .txt" and
"Set-Content A_1.txt" would be "overwrite the existing file".
I hope someone will help me, thank you! <3 <3 <3
You already have some of the solution in your first code snippet, you need to iterate over the files again to perform the replace and save.
$txtFiles = Get-ChildItem -Name *.txt
ForEach ($file in $txtFiles) {
(Get-Content $file) | ForEach-Object {
$_ -replace '%','percent'
} | Set-Content $file
}
The first line adds all the text files to an array, the foreach loop iterates over the files of the array and grabs the content of the file and unloads it - that's the reason for the parenthesis, the Foreach-Object then iterates over the content of the file and saves it to the same file name as before.
If you skip the parentheses around Get-Content $file the file would still be loaded into memory and you would get an error message about not being able to save the file.

Batch command to remove a string pattern from input file

I'm very new to scripting.
I have a couple of files File1.txt and File2.txt. "RemPattern" is the pattern which I'm expecting to find and remove recursively from the above files.
Is it possible to remove them with the help of any windows or powershell batch command?
I have seen Get-Content can be used to remove an entire line of the matched pattern, but it doesn't fit for my case.
(Get-Content 'File1.txt') -notmatch 'RemPattern' | Set-Content 'File1.txt'
Is it required to write a batch file to achieve this or is it possible to do it by batch commands?
You can try out the -replace instead of -nomatch.
(Get-Content 'D:\File.txt') -replace 'RemPattern' | Set-Content 'D:\File.txt'
I was assuming that you wanted to recurse through a set of files and not do them by manually typing the filenames. So you can:
Get-ChildItem F:\ -Filter File*.txt | Foreach-Object{
(Get-Content $_.FullName) | Foreach-Object {$_ -replace 'RemPattern'} | Set-Content $_.FullName
}
The filter here simply checks File*.txt which in your example will do the replacement for both File1.txt and File2.txt without havign to type out each file manually per line. You can change the filter as you please.

How do I remove carriage returns from text file using Powershell?

I'm outputting the contents of a directory to a txt file using the following command:
$SearchPath="c:\searchpath"
$Outpath="c:\outpath"
Get-ChildItem "$SearchPath" -Recurse | where {!$_.psiscontainer} | Format-Wide -Column 1'
| Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
What I end up with when I do this is a txt file with the information I need, but it adds numerous carriage returns I don't need, making the output harder to read.
This is what it looks like:
c:\searchpath\directory
name of file.txt
name of another file.txt
c:\searchpath\another directory
name of some file.txt
That makes a txt file that requires a lot of scrolling, but the actual information isn't that much, usually a lot less than a hundred lines.
I would like for it to look like:
c:\searchpath\directory
nameoffile.txt
c:\searchpath\another directory
another file.txt
This is what I've tried so far, not working
$configFiles=get-childitem "c:\outpath\*.txt" -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace "'n", ""} |
Set-Content $file.PSPath
}
I've also tried 'r but both options leave the file unchanged.
Another attempt:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line}'
| Set-Content -Path c:\outpath\contents2.txt
When I run that string without the Set-content at the end, it appears exactly as I need it in the ISE, but as soon as I add the Set-Content at the end, it once agains carriage returns where I don't need them.
Here's something interesting, if I create a text file with a few carriage returns and a few tabs, then if I use the same -replace script I've been using, but uset to replace the tabs, it works perfect. Butr and n do not work. It's almost as though it doesn't recognize them as escape characters. But if I addr and `n in the txt file then run the script, it still doesn't replace anything. Doesn't seem to know what to do with it.
Set-Content adds newlines by default. Replacing Set-Content by Out-File in your last attempt in your question will give you the file you want:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line} |
Out-File -FilePath c:\outpath\contents2.txt
It's not 'r (apostrophe), it's a back tick: `r. That's the key above the tab key on the US keyboard layout. :)
You can simply avoid all those empty lines by using Select-Object -ExpandProperty Name:
Get-ChildItem "$SearchPath" -Recurse |
Where { !$_.PSIsContainer } |
Select-Object -ExpandProperty Name |
Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
... if you don't need the folder names.