I have a log file with ^M embedded throughout. I would like to replace the ^M with a single space.
I have tried variations on this:
(Get-Content C:\temp\send.log) | Foreach-Object {$_ -replace "^M", ' '} | Set-Content C:\temp\send.out
The output file contains a newline where each ^M had been, not at all what I was looking for...
The problem I am trying to solve involves examining the last $cnt lines of the file:
$new = Get-Content $fn | Select-Object -Last $cnt;
$new
When I display $new, the ^M are interpreted as CR/LF.
How can I remove/replace the ^M? Thanks for any pointers....
Sounds like ^M is not being replaced by your -replace method, it's likely the replace method is trying to replace capital letter M at the beginning of the string (^). Upon opening the file, ^M is then being interpreted as a carriage return.
Perhaps try replacing the carriage returns (^M) before displaying the contents:
(Get-Content C:\temp\send.log) |
Foreach-Object {$_ -replace "`r", ' '} |
Set-Content C:\temp\send.out
or
$new = Get-Content $fn | Select-Object -Last $cnt;
$new.replace("`r"," ")
Could this be as simple as escaping the ^ character? If you only need the last $count lines of the file you can use the -Tail parameter on Get-Content. Depending if you need to match ^M as case sensitive you might opt for -creplace instead of -replace.
Get-Content $inputfile -Tail $count | ForEach-Object { $_ -creplace '\^m',' ' } | Set-Content $outputfile
This isn't an answer, but since you asked for a few pointers, this might help set things straight.
Try this:
$new = Get-Content $fn | Select-Object -Last $cnt;
$new
$new.gettype()
$new[0].gettype()
I expect you're going to see that $new is an array of objects, and that $new[0] is a string. I'm going to suggest that $new[0] doesn't contain CR or LF or CRLF or anything like that. And I'm going to suggest that, when you ask for the display of $new in its entirety, what you are getting is each string ($new[0] followed by $new[1] ...) with CRLF inserted as a separator.
If I'm right, replacing CR or CRLF with space isn't going to do you any good at all. It's the CRLFs that are being inserted on output to a file that are preventing you from succeeding.
This is as far as I got towards solving your problem.
Related
I try to delete carriage return in a file, all lines have a "}" at end, but some lines, have a return carriage and the "}" its down.... Here an example of my code and file, but doesn't work. Thank You Very Much!!
Original File
The line with "INGENIERIA Y SERVICIOS LOS NOGALES SPA" it's the conflict.
Expected Result
Code:
$InputFile='Original.txt'
$OutPutFile='NewFile.txt'
(Get-Content $InputFile) | ForEach-Object -Begin {
$results = #()
} -Process {
$out = $.Split("}").GetUpperBound(0)
[int]$iOut = [int]$out
if($iOut -lt 1){$.Replace("`r`n","")}else{$_}
} | Set-Content $OutPutFile
Thanks!
You may do the following:
(Get-Content $InputFile -Raw) -replace '(?<!})\r\n' |
Set-Content $outputfile
Reading a file using Get-Content without the -Raw or -ReadCount parameters, reads each line and outputs it as an array element. A line is output once its delimiter has been found. The default delimiter for Get-Content is the end of line character. -Raw allows newline characters to be preserved and the file is read as a single string.
(?<!}) is a negative lookbehind matching only when the preceding character is not a }. Then we simply match \r\n for CRLF.
I need to loop through multiple text files and check for a $ value in position 7 on each line of text and replace it with an * when found. But ONLY when it is in position 7. I do not want to change it if it is found in other positions. This is as far as I have gotten. Any help would be greatly appreciated.
Get-ChildItem 'C:\*.txt' -Recurse |
foreach $line in Get-Content $_ {
$linePosition1to5 = $line.Substring(0,6)
$linePosition7 = $line.Substring(6,1)
$linePositionRest = $line.Substring(8)
if($linePosition7 = "$"){
$linePosition7 = "*"
}
$linePosition1to5 + $linePosition7 + $linePositionRest |
Set-Content $_
}
Is there something that doesn't work in your example, or just that all the nested substrings are annoying to work with?
I'd use regex for this one. e.g.
$Lines = Get-Content -Path "C:\examplefile.txt" -raw
$Lines -replace '(?m)(^.{6})\$', '$1*'
To explain the regex:
?m indicates that it's multiline, required because I used raw get-content rather than pulling an array. Array would work too, just needs a loop like you did.
^.{6} line start plus any 6 characters (capture group 1)
$ escaped dollar character
$1* Capture group 1 left as is, dollar replaced with *, anything else not captured and therefore left untouched.
Thanks for code and the explanation. I realized that I left out the -raw option and it did work. Putting it back in it seems to add a line to the end of each file. Unless you can think of reason why I shouldn't I was going to leave it out.
Get-ChildItem 'C:\TEST\*.txt' -Recurse | ForEach {
(Get-Content $_ | ForEach { $_ -replace '(?m)(^.{6})\$', '$1*'}) |
Set-Content $_
}
I know that I can use:
gc c:\FileWithEmptyLines.txt | where {$_ -ne ""} > c:\FileWithNoEmptyLines.txt
to remove empty lines. But How I can remove them with '-replace' ?
I found a nice one liner here >> http://www.pixelchef.net/remove-empty-lines-file-powershell. Just tested it out with several blanks lines including newlines only as well as lines with just spaces, just tabs, and combinations.
(gc file.txt) | ? {$_.trim() -ne "" } | set-content file.txt
See the original for some notes about the code. Nice :)
This piece of code from Randy Skretka is working fine for me, but I had the problem, that I still had a newline at the end of the file.
(gc file.txt) | ? {$_.trim() -ne "" } | set-content file.txt
So I added finally this:
$content = [System.IO.File]::ReadAllText("file.txt")
$content = $content.Trim()
[System.IO.File]::WriteAllText("file.txt", $content)
You can use -match instead -eq if you also want to exclude files that only contain whitespace characters:
#(gc c:\FileWithEmptyLines.txt) -match '\S' | out-file c:\FileWithNoEmptyLines
Not specifically using -replace, but you get the same effect parsing the content using -notmatch and regex.
(get-content 'c:\FileWithEmptyLines.txt') -notmatch '^\s*$' > c:\FileWithNoEmptyLines.txt
To resolve this with RegEx, you need to use the multiline flag (?m):
((Get-Content file.txt -Raw) -replace "(?m)^\s*`r`n",'').trim() | Set-Content file.txt
If you actually want to filter blank lines from a file then you may try this:
(gc $source_file).Trim() | ? {$_.Length -gt 0}
You can't do replacing, you have to replace SOMETHING with SOMETHING, and you neither have both.
This will remove empty lines or lines with only whitespace characters (tabs/spaces).
[IO.File]::ReadAllText("FileWithEmptyLines.txt") -replace '\s+\r\n+', "`r`n" | Out-File "c:\FileWithNoEmptyLines.txt"
(Get-Content c:\FileWithEmptyLines.txt) |
Foreach { $_ -Replace "Old content", " New content" } |
Set-Content c:\FileWithEmptyLines.txt;
file
PS /home/edward/Desktop> Get-Content ./copy.txt
[Desktop Entry]
Name=calibre
Exec=~/Apps/calibre/calibre
Icon=~/Apps/calibre/resources/content-server/calibre.png
Type=Application*
Start by get the content from file and trim the white spaces if any found in each line of the text document. That becomes the object passed to the where-object to go through the array looking at each member of the array with string length greater then 0. That object is passed to replace the content of the file you started with. It would probably be better to make a new file...
Last thing to do is reads back the newly made file's content and see your awesomeness.
(Get-Content ./copy.txt).Trim() | Where-Object{$_.length -gt 0} | Set-Content ./copy.txt
Get-Content ./copy.txt
This removes trailing whitespace and blank lines from file.txt
PS C:\Users\> (gc file.txt) | Foreach {$_.TrimEnd()} | where {$_ -ne ""} | Set-Content file.txt
Get-Content returns immutable array of rows. You can covert this to mutable array and delete neccessary lines by index.Particular indexex you can get with match. After that you can write result to new file with Set-Content. With this approach you can avoid empty lines that powershell replace tool leaves when you try to replace smthing with "". Note that I dont guarantee perfect perfomance. Im not a professional powershell developer))
$fileLines = Get-Content $filePath
$neccessaryLine = Select-String -Path $filePath -Pattern 'something'
if (-Not $neccessaryLine) { exit }
$neccessaryLineIndex = $neccessaryLine.LineNumber - 1
$updatedFileContent = [System.Collections.ArrayList]::new($fileLines)
$updatedFileContent.RemoveAt($neccessaryLineIndex)
$updatedHostsFileContent.RemoveAt($domainInfoLineIndex - 1)
$updatedHostsFileContent | Set-Content $hostsFilePath
Set-Content -Path "File.txt" -Value (get-content -Path "File.txt" | Select-String -Pattern '^\s*$' -NotMatch)
This works for me, originally got the line from here and added Joel's suggested '^\s*$': Using PowerShell to remove lines from a text file if it contains a string
I need to place System.Object[] for some columns in a csv file. I tried 3 different method but none of them are working. System.Object[] is put in by powershell when that object is empty or something.
$file = "c:\output.csv"
(gc $file) -replace "'system.object[]'", ""
[io.file]::readalltext($file).replace("'system.object[]'","")
(Get-Content $file | ForEach-Object { $_ -replace "system.object[]", "" } ) | Set-Content $file
I added following code to the variable that containing System.Object[] on output. and it's seems to be working. and now I dont have to do the replacement at file level.
"Access Code" = (#($AccessCode) | Out-String).Trim()
The bracers and the dot ([, ], .) need all to be escaped. Furthermore remove the double quotation marks, just keep the single ones. Also think about using creplace, in case you want to work case insensitive. So the command would look like this:
(gc $file) -replace 'system\.object\[\]', ''
In case you want to write everything to a new file:
(gc $file) -replace 'system\.object\[\]', ''|out-file "test2.txt" -encoding ASCII
Just use Escape character
(gc $file) -replace 'system.object\[\]', ""
The characters '[' and ']' are used for Regex pattern. You must use Escape
character '\' to tell Powershell that This is a regular chars
I'm looking for a script, doesn't have to be in PS but must run under Windows, that converts a one column text file like below
abc
def
ghi
into
'abc',
'def',
'ghi'
I'm currently making this change in Excel using =concatenate, but a script would be better.
Use can use a regular expression to insert characters at beginning and end.
get-content ./myonlinecolumn.txt | foreach {$_ -replace "^","'" -replace "`$","',"}
Or you could use the format operator -f:
get-content ./myonlinecolumn.txt | foreach {"'{0}'," -f $_ }
Its a bit more work to remove the last trailing comma, but this also possible
$a = get-content ./myonlinecolumn.txt
get-content ./myonlinecolumn.txt | foreach { if ($_.readcount -lt $a.count) {"'{0}'," -f $_ } else {"'{0}'" -f $_ }}
My first idea was similar to what Chad already wrote, that is a check on the line number. So I've tried a different solution. Not very nice but I post it too :)
((gc c:\before.txt | % {"'"+$_+"'"} ) -join ",*").split("*") | out-file c:\after.txt
You can just use
(gc myfile | %{"'$_'"}) -join ',
'
or, if you love escapes:
(gc myfile | %{"'$_'"}) -join ",`n"
This loads the file into an array of strings (Get-Content), then processes each string by putting it into single quotes. (Use `"'$($_.Trim())'" if you need to trim whitespace, too). Then the lines are joined with a comma and line break (those can be embedded directly into strings).
If your values can contain single quotes (which need to be escaped) it's trivial to stick that in there, too:
(gc myfile | %{"'$($_.Trim() -replace "'","''")'"}) -join ",`n"