Batch script to replace a two word string containing parentheses - windows

I have a .h document with over 10000 lines of code. It looks like this:
#define GHL_NO_OF_EVENTS_CORE_2 (512uL)
#define GHL_NO_OF_CORES (1)
#define GHL_CFG_IS_GW_SAFETY_OS (1)
I need to change the comment #define GHL_CFG_IS_GW_SAFETY_OS (1) to #define GHL_CFG_IS_GW_SAFETY_OS (0)
I have tried a lot using this command but it seems like it doesn't work because of the parentheses:
powershell -Command "(gc path-to-file\Cfg.h -encoding \"Default\") -replace 'GHL_CFG_IS_GW_SAFETY_OS (1)', 'GHL_CFG_IS_GW_SAFETY_OS (0)' | Out-File -encoding \"Default\" path-to-file\Cfg.h"
Note: I can't escape the parentheses characters with ` or ^, it just doesn't work.

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

Inno setup pass command line argument into #define

I want to pass an argument into Inno setup and ultimately create a string which has this argument (which happens to be the year) in the middle of some text e.g. if I pass MyYear=2018 to the Inno setup command line I want to make
AppName=Some text 2018 some more text
I tried to do
#define MyAppName="Some text" {#MyYear} "some more text"
and also
#define AppName1 "Some text"
#define AppName2 "some more text"
#define MyAppName={#AppName1} {#MyYear} {#AppName2}
then in setup
AppName={#MyAppName}
but it didn't like me passing the argument into the #define part - is this not allowed?
I have ended up with something that feels rather clumsy (but works) namely creating 2 strings which are either side of the argument i want to pass in and then appending the 3 strings together...
#define AppName1 "Some text"
#define AppName2 "some more text"
then in setup
AppName={#AppName1} {#MyYear} {#AppName2}
Do it like this:
#define MyAppName AppName1 + ' ' + MyYear + ' ' + AppName2

Batch file to read a txt with special characters and replace a word in it

I'm trying to make a batch file that reads a txt file "ayylmao.txt" and find a specific word "hello" and replaces it with "xello".
The thing is that the "ayylmao.txt" contains specific characters.
Ayylmao.txt looks something like this:
‹‹R‹Ę‹/M‹;Ču‹č˙˙˙‹‹#‰‹‹#CëC;Đu‹čq˙˙˙‹‹#C‹D$‰;7u®‹Ó‹Ćčúţ˙˙„Ŕu3Ŕ‰YZ]_^[ĂŤ# SVWUÄđ‰$‹ô‹‰D$‹
‹‹#;Č‚† ‹Ř‹>_‹ůz;ßrv;Ču!‹B‹A‹B‹)B‹x uV‹čđţ˙˙ëM‹Ř‹>_‹ůz;ßu
‹B‹)Bë3‹Z‰\$‹>‹‹.}+ű‰|$+Č‹‰HŤT$‹čMţ˙˙„Ŕu3 hello Ŕë°ë‹‹ ‰‹;D$…Y˙˙˙3ŔÄ]_^[ĂSVW‹Ú‹đţ }ľ ëĆ˙˙ ć ˙˙‰sjh Vj
You can see the "hello" word in the last line. I want the batch to go to the process and give me a ayylmao1.txt that looks like this:
‹‹R‹Ę‹/M‹;Ču‹č˙˙˙‹‹#‰‹‹#CëC;Đu‹čq˙˙˙‹‹#C‹D$‰;7u®‹Ó‹Ćčúţ˙˙„Ŕu3Ŕ‰YZ]_^[ĂŤ# SVWUÄđ‰$‹ô‹‰D$‹
‹‹#;Č‚† ‹Ř‹>_‹ůz;ßrv;Ču!‹B‹A‹B‹)B‹x uV‹čđţ˙˙ëM‹Ř‹>_‹ůz;ßu
‹B‹)Bë3‹Z‰\$‹>‹‹.}+ű‰|$+Č‹‰HŤT$‹čMţ˙˙„Ŕu3 xello Ŕë°ë‹‹ ‰‹;D$…Y˙˙˙3ŔÄ]_^[ĂSVW‹Ú‹đţ }ľ ëĆ˙˙ ć ˙˙‰sjh Vj
You can see that "hello" is now "xello".
I found this batch file that replaces a word from a text file:
#echo off
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL DISABLEDELAYEDEXPANSION
if "%~1"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %3|find /n /v """') do (
set "line=%%B"
if defined line (
call set "line=echo.%%line:%~1=%~2%%"
for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
) ELSE echo.
)
This code works for files that don't have specific characters very good if use it like this:
code.bat "hello" "xello" "ayylmao.txt">"ayylmao1.txt"
This code only types in ayylmao1.txt few special characters but replaces hello. I want all the special characters typed in there.
I made it like this:
chcp 1252
code.bat "hello" "xello" "ayylmao.txt">"ayylmao1.txt"
But it didn't work. It worked just like the first code.
If there is a way in PowerShell to do this I'd be glad to hear it.
What you have there looks like a binary file, not a text file, despite the extension. Batch is no good for editing binary files. In PowerShell it's doable, but you need to resort to working with the data bytes instead of simple text.
This is a basic example that will find the first occurrence of the string "hello" in your file and replace it with "xhello":
$f = 'C:\path\to\ayylmao.txt'
$stext = 'hello'
$rtext = [char[]]'xhello'
$len = $stext.Length
$offset = $len - 1
$data = [IO.File]::ReadAllBytes($f)
# find first occurrence of $stext in byte array
for ($i=0; $i -lt $data.Count - $offset; $i++) {
$slice = $data[$i..($i+$offset)]
if (-join [char[]]$slice -eq $stext) { break }
}
# Once you know the beginning ($i) and length ($len) of the array slice
# containing $stext you can "cut up" $data and concatenate the slices before
# and after $stext to the byte sequence you want to insert ($rtext):
#
# |<-- $stext -->|
# [...]['h','e','l','l','o'][...] <-- $data
# ^ ^ ^ ^
# | | | |
# | $i | $i+$len
# $i-1 $i+$offset (== $i+$len-1)
#
$rdata = $data[0..($i-1)] + [byte[]]$rtext + $data[($i+$len)..($data.Count-1)]
[IO.File]::WriteAllBytes($f, $rdata)
You'll need to adjust this code if you want the replacement to work differently (replace other occurrences as well, replace a different occurrence, …).
But it didn't work. It worked just like the first code. Help ?
This batch code is coming from this site and there is a link to discussion why it doesn't work with special characters.
Yes, the PowerShell replace command can replace the string and keep the special characters. To call it from within your batch script, use the following line
powershell -command "(get-content Ayylmao.txt) -replace 'hello','xello' | set-content Ayylmao.txt"
If you want to enter your parameters from the command line, then the line would be
powershell -command "(get-content %3) -replace '%1','%2' | set-content %4"
And if you want to use variables defined in the batch script, it is the same as you would for any batch script
set file=Ayylmao.txt
set Search_criteria=hello
set Replace_criteria=xello
powershell -command "(get-content %file%) -replace '%Search_criteria%','%Replace_criteria%' | set-content %file%"

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

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

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