How to replace a backslash CR LF with a <br> with powershell - windows

I've tried many combinations of attempting to replace a "\ cr lf" with an html "br" tag after "foo".
My input file (tempA.txt) looks like this (there is a cr lf at the end of line 1 after the slash):
foo\
bar
I'm using a powershell command (within a bat file) like this:
type c:\temp\tempA.txt
powershell -Command "(gc c:\temp\tempA.txt) -replace '\\`r`n', '<br>' | Out-File c:\temp\tempB.txt"
type c:\temp\tempB.txt
My output file (tempB.txt) isn't changing. I want the output file to contain
foo<br>bar
How do you replace the "\ cr lf" with a simple html "br" tag?

Change your first -replace operator arg to use a double quoted string:
... -replace "\\`r`n", '<br>'
A single quoted string in PowerShell is a literal string so the backtick doesn't work to escape characters.

Get-Content will split your file into an array of lines. Based on this, you can just replace \ with <br> and join the lines together.
(gc c:\temp\tempA.txt) -replace '\\', '<br>' -join '' | Out-File c:\temp\tempB.txt

Related

Powershell - Can't unlock BitLocker as 256 characters long password contains special characters with single double quotes

Here's the background and I have no clue beyond this so tell me how to move ahead from this!
PS C:\> $SecureString = ConvertTo-SecureString "fjuksAS1337" -AsPlainText -Force
PS C:\> Unlock-BitLocker -MountPoint "E:" -Password $SecureString
My password here is:
cF;TA" X%jl"\G{d}rcVzNI=Inps#|P,o{~"k<+#?bm)PjQf^\c8EB! (cL.ZyA.v/yYQ#,!#gN'%"VwlNFs)(h\1Uf#cFdr7BU%zDA;&2R_3w3C3td-Nm,^VFE$cF>N{ol0Y~qR2i`Vm%Q#ckh0]#ZE!ijnirg5k?bj\L;88wBhg8QqO^/T64D#O6Q'H"")/I5(d4v7RC`jH=JH+,Zy*TY4MEf~.b7?;';zLEmB>F^S7aBrUfnN&(Vuhjw}Z3w5
As you see it has multiple single and double quotes which breaks the SecureString command output getting nowhere.
I need to use this password in order to unlock BitLocker drive as the UI throws wrong password error and recovery password of 48 digits is unfortunately lost!
Please help as I am having no idea here at all!
Use a single-quoted here-string.
Anything you put in there won't be escaped in any way.
Example
$PlainTextPassword = #'
cF;TA" X%jl"\G{d}rcVzNI=Inps#|P,o{~"k<+#?bm)PjQf^\c8EB! (cL.ZyA.v/yYQ#,!#gN'%"VwlNFs)(h\1Uf#cFdr7BU%zDA;&2R_3w3C3td-Nm,^VFE$cF>N{ol0Y~qR2i`Vm%Q#ckh0]#ZE!ijnirg5k?bj\L;88wBhg8QqO^/T64D#O6Q'H"")/I5(d4v7RC`jH=JH+,Zy*TY4MEf~.b7?;';zLEmB>F^S7aBrUfnN&(Vuhjw}Z3w5
'#
$SecureString = ConvertTo-SecureString $PlainTextPassword -AsPlainText -Force
For a quick reference:
# verbatim string. Nothing get processed. Single-quotes within the string need to
# be doubled down.
$sq = 'Hello '' world.'
# Expandable string. Stuff that can be expanded will be.
# Double-quotes within the string need to be doubled down or preceded by a backtick `
$dq = "Hello `" "" world"
# verbatim here string. single-quotes within the string do not need to be escaped
# This is the way to go for multiline strings
$sqh = #'
Hello ' World
'#
# Expandable here string. Double quotes within the string do not need to be escaped.
# This is the way to go for multiline strings
$dqh = #"
Hello " World
"#
Reference
About_Quoting_Rules

Windows Powershell script to find and replace a string after a particular string

I am currently working to convert AS3 class to JavaScript using Powershell script.
Below is the sample code needs to be converted.
package somePackageName
{
class someClassName
{
// other codes
}
}
I need the entire package block to be removed and "class someClassName{" should be converted to "function someClassName(){".
The "someClassName" can be any string.
And I need the output like this.
function someClassName()
{
}
This is what I tried.
$l1 = Get-Content $dest | Where-Object {$_ -like 'class'}
$arr = $l1 -split ' '
$n1 = "function "+ $arr[1] + "() " +$arr[2]
(Get-Content $dest) -creplace $l1, $n1 | Set-Content $dest
I can able to achieve what I intended if the opening brace is in same line as the package declaration line. As Powershell checks line by line, I am stuck if the opening brace present in next line.
Regex based solution
Depending on your willingness to post process this or accept leading spaces you could use this regex to remove the block outside of the class and replace with a function declaration. This is messier than it needs to be but safer since we cannot guess what // other codes is. You could just match the whole class block outright but if there are other curly braces in there it would muddy the regex.
PS M:\> (Get-Content -Raw $dest) -replace "(?sm).*?class (\w+)(.*)}",'function $1()$2'
function someClassName()
{
// other codes
}
See Regex101 for more detail on what the regex is doing.
Basically dump everything until the word class (first time). Then keep everything until the last closing brace
Note the leading space in the greater portion. This is honoring the existing space. To account for this we need to calculate the indentation. Simply removing all leading space would break existing indentation in the class/function.
So a solution like this might be preferred:
# Read in the file as a single string
$raw = (Get-Content -Raw $dest)
# Using the line that has the class declaration measure the number of spaces in front of it.
[void]($raw -match "(?m)^(\s+)class")
$leadingSpacesToRemove = $Matches[1].Length
# Remove the package block. Also remove a certain amount of leading space.
$raw -replace "(?sm).*?class (\w+)(.*)}",'function $1()$2' -replace "(?m)^\s{$leadingSpacesToRemove}"
Less regex
Seems filtering the lines with no leading spaces is an easy way to narrow down to what you want.
Get-Content $dest | Where-Object{$_.StartsWith(" ")}
From there we still need to replace the "class" and deal with the leading spaces. For those we are going to use similar solutions to what I showed above.
# Read in the file as a single string. Skipping the package wrapper since it has no leading spaces.
$classBlock = Get-Content $dest | Where-Object{$_.StartsWith(" ")}
# Get the class name and the number of leading spaces.
$classBlock[0] -match "^(\s+)class (\w+)" | Out-Null
$leadingSpacesToRemove = $matches[1].Length
$className = $matches[2]
# Output the new declaration and the trimmed block.
# Using an array to start so that piping output will be in one pipe
#("function $className()") + ($classBlock | Select -Skip 1) -replace "^\s{$leadingSpacesToRemove}"
Both solutions try to account for your exact specifications and account for the presence of weird stuff inside the class block.
I'd suggest using regex:
#class myclass -> function myclass()
#(Get-Content $dest) -creplace 'class\s(.+)', 'function $1()' |
Set-Content $dest
This will capture the class declaration and replace it with a backreference to the class name capture.

Append forward slash to the end of certain line in a file

I have a file (Flags.txt) that looks like this:
...
C_INCLUDES = ... ... .../xxx
...
CXX_INCLUDES = ... ... .../yyy
where the line with C_INCLUDES can end with any string (here e.g xxx).
At the end, the file shall look like this:
...
C_INCLUDES = ... ... .../xxx/
...
CXX_INCLUDES = ... ... .../yyy
Therefore I want to use a windows batch file (not possible to use sed or awk) to search for the name C_INCLUDES and append at the end of the line the forward slash (but could be any smbol e.g "xxxz" or "xxx!" )?
I tried the solution from:
https://social.technet.microsoft.com/Forums/scriptcenter/en-US/fa09e27d-9f6b-4d4e-adda-f0663e0a9dde/append-string-to-text-file-at-end-of-line-starting-with-blah?forum=ITCG
$original = "flags.txt"
$tempfile = "tmp.txt"
get-content $original | foreach-object {
if ($_ -match "^C_INCLUDES") {
$_ + "/" >> $tempfile
}
else {
$_ >> $tempfile
}
}
copy-item $tempfile $original
remove-item $tempfile
But it don't work
Thanks
You imply you cannot use 3rd party (non-native) exe files such as sed. But you can use a batch file.
So you should have no problem using JREPL.BAT - a regular expression find/replace text processing utility. JREPL is pure script (hybrid batch/JScript) that runs natively on any Windows machine from XP onward - no 3rd party exe file required.
Full documentation is available from the command line via jrepl /?, or jrepl /?? for paged help.
Once you have JREPL.BAT, then the following one liner is all that is needed. It looks for any line that begins with C_INCLUDES and doesn't already end with /, and appends / to any line that matches.
jrepl "^C_INCLUDES .*(?=.$)[^/]" "$&/" /f "Flags.txt" /o -
Since JREPL is a batch script, you must use call jrepl if you put the command within another batch script.

Can't rename item in powershell because it's null

qqq.exe exists.
$DB is correct, I use it other times just fine.
$DB = Get-Content C:\Users\asd\Desktop\Farm\AccountList.txt
foreach ($x in $DB){
Rename-Item C:\Users\asd\Desktop\Farm\$x\qqq.exe $x.exe
}
Rename-Item : Cannot bind argument to parameter 'NewName' because it is null.
At C:\Users\asd\Desktop\Farm\test2.ps1:3 char:57
+ Rename-Item C:\Users\asd\Desktop\Farm\$x\qqq.exe $x.exe
+ ~~~~~~
+ CategoryInfo : InvalidData: (:) [Rename-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RenameItemCommand
When the powershell parser sees an argument starting with a $, it treats it as an expression, meaning that it will try to evaluate it as code.
Since the string $x doesn't have a property named exe, the expression results in $null and Rename-Item throws the error you see.
If you use a double-quoted string instead, the parser will stop evaluating $x after the dot:
Rename-Item C:\Users\asd\Desktop\Farm\$x\qqq.exe "$x.exe"
From Get-Help about_Parsing:
When processing a command, the Windows PowerShell parser operates
in expression mode or in argument mode:
- In expression mode, character string values must be contained in
quotation marks. Numbers not enclosed in quotation marks are treated
as numerical values (rather than as a series of characters).
- In argument mode, each value is treated as an expandable string
unless it begins with one of the following special characters: dollar
sign ($), at sign (#), single quotation mark ('), double quotation
mark ("), or an opening parenthesis (().

UNIX format files with Powershell

How do you create a unix file format in Powershell? I am using the following to create a file, but it always creates it in the windows format.
"hello world" | out-file -filepath test.txt -append
As I understand, the new line characters CRLF make it to be a Windows format file whereas the unix format needs only a LF at the end of the line. I tried replacing the CRLF with the following, but it didn't work
"hello world" | %{ $_.Replace("`r`n","`n") } | out-file -filepath test.txt -append
There is a Cmdlet in the PowerShell Community Extensions called ConvertTo-UnixLineEnding
One ugly-looking answer is (taking input from dos.txt outputting to unix.txt):
[string]::Join( "`n", (gc dos.txt)) | sc unix.txt
but I would really like to be able to make Set-Content do this by itself and this solution does not stream and therefore does not work well on large files...
And this solution will end the file with a DOS line ending as well... so it is not 100%
I've found that solution:
sc unix.txt ([byte[]][char[]] "$contenttext") -Encoding Byte
posted above, fails on encoding convertions in some cases.
So, here is yet another solution (a bit more verbose, but it works directly with bytes):
function ConvertTo-LinuxLineEndings($path) {
$oldBytes = [io.file]::ReadAllBytes($path)
if (!$oldBytes.Length) {
return;
}
[byte[]]$newBytes = #()
[byte[]]::Resize([ref]$newBytes, $oldBytes.Length)
$newLength = 0
for ($i = 0; $i -lt $oldBytes.Length - 1; $i++) {
if (($oldBytes[$i] -eq [byte][char]"`r") -and ($oldBytes[$i + 1] -eq [byte][char]"`n")) {
continue;
}
$newBytes[$newLength++] = $oldBytes[$i]
}
$newBytes[$newLength++] = $oldBytes[$oldBytes.Length - 1]
[byte[]]::Resize([ref]$newBytes, $newLength)
[io.file]::WriteAllBytes($path, $newBytes)
}
make your file in the Windows CRLF format. then convert all lines to Unix format in new file:
$streamWriter = New-Object System.IO.StreamWriter("\\wsl.localhost\Ubuntu\home\user1\.bashrc2")
$streamWriter.NewLine = "`n"
gc "\\wsl.localhost\Ubuntu\home\user1\.bashrc" | % {$streamWriter.WriteLine($_)}
$streamWriter.Flush()
$streamWriter.Close()
not a one-liner, but works for all lines, including EOF. new file now shows as Unix format in Notepad on Win11.
delete original file & rename new file to original, if you like:
ri "\\wsl.localhost\Ubuntu\home\user1\.bashrc" -Force
rni "\\wsl.localhost\Ubuntu\home\user1\.bashrc2" "\\wsl.localhost\Ubuntu\home\user1\.bashrc"
Two more examples on how you can replace CRLF by LF:
Example:
(Get-Content -Raw test.txt) -replace "`r`n","`n" | Set-Content test.txt -NoNewline
Example:
[IO.File]::WriteAllText('C:\test.txt', ([IO.File]::ReadAllText('C:\test.txt') -replace "`r`n","`n"))
Be aware, this does really just replace CRLF by LF. You might need to add a trailing LF if your Windows file does not contain a trailing CRLF.

Resources