Replace letters in a text using symbols through CMD - text

I need some help in using the CMD. I am an amateur programmer so please be gentle with technical terms! However, I think that what I need is quite simple for a programmer!
I am developing a simple text encode/decode bot (with WinAutomation software) that will run in a very slow MS Windows PC. I use my own encoding/decoding method for years so I am not interested in using a ready-made solution.
I want to be able to replace any letter in any text (as a variable) with symbols and vice versa using the command line.
Example:
“a” will be “[?]”
“b” will be “[*]”
“c” will be “[/]”
Vice versa
“[?]” will be “a”
“[*]” will be “b”
Etc
I am currently using a loop to do the 130 letter replacements. Loop is executed very fast and causes CPU and memory overload in slow PC. From the other hand, If I place a waiting action at the end of the loop (1 sec minimum), the replacements will finish in 130 seconds. This is time wasting!
I need a ONE LINE code in order to make the replacements at once through CMD.
A programmer suggested me the piece of code below that seems to work but it is not one line
SET _test=12345abcabc
SET _result=%_test:ab=xy%
SET _result=%_result:1=2%
How can I convert it in one line? I have tried && and || but I am doing something wrong!
Below I have uploaded an image from WinAutomation’s Run Command Window. You can view it here https://imgur.com/3hbcCZE.
Thank you

This can be done in one line. ENABLEDELAYEDEXPANSION needs to be set. The code before and after the one (1) line is just to ensure that the variables are set to nothing and show that they are set to nothing.
C:>type and.bat
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "_test="
SET "_result="
ECHO _test is %_test%, _result is %_result%
REM Here is the one (1) line.
SET "_test=12345abcabc" && SET "_result=!_test:ab=xy!" && SET "_result=!_result:1=2%!
ECHO _test is %_test%, _result is %_result%
Here is a result from running the script.
C:>CALL and.bat
_test is , _result is
_test is 12345abcabc, _result is 22345xycxyc

Related

using special characters in parameters and variables in batch without external file use

Before you go marking this as a duplicate hear me out
My question;
A: has different requirements than all the others (which are basically "whats an escape character?") Including: not having to use an external file to enter in parameters to functions
B: questions the existence of this mess rather than accepting 'no' or 'its complicated' as the answer
C: understands that there are escape characters that already exist and ways to work around that
D: comes from a different skill level and isn't a 2-7 years old question
E: requires the use of quotes rather than something like [ because quotes are the only thing that works with spaced strings
Also before ya'll say I didn't try stuff
I read these (all of it including comments and such):
Batch character escaping
http://www.robvanderwoude.com/escapechars.php
https://blogs.msdn.microsoft.com/oldnewthing/20091029-00/?p=16213
using batch echo with special characters
Escape angle brackets in a Windows command prompt
Pass, escape and recognize Special Character in Windows Batch File
I didn't understand that all fully, because to fully understand all that I'd have to be much better at batch but here is what I gleaned:
So I understand theres a whole table of escape sequences, that ^ is the most used one, that you can use Delayed Expansion to do this task so that the characters don't get parsed immediately, just 'expanded' at runtime, but then that the Enable Delayed expansion thing doesn't always work because with pipe characters, the other files/things being piped to/from don't inherit the expansion status so
A: you have to enable it there too
B: that forces you to use that expansion
C: it requires multiple escape characters for each parsing pass of the CLI which apparently is hard to determine and ugly to look at.
This all seems rather ridiculous, why wasn't there some sort of creation to set a string of odd inputs to literal rather than process the characters. Why wasn't it just a simple flag upon some super duper special character (think alt character) that would almost never appear unless you set the font to wingdings. Why does each parsing pass of pipe characters remove the escape characters? That just makes everything insane because the user now has to know how many times that string is used. Why hasn't a tool been developed to auto scan through odd inputs and auto escape them? We have a table of the rules, is it really that hard? Has it been done already? What would it require that's 'hard'?
Down the rabbit hole we go
How did I get here you ask? Well it all started when I made a simple trimming function and happened upon one of the biggest problems in batch, escaping characters when receiving inputs. The problem is alot of my inputs to my trimming function had quotes. Quotes are escaped by using "" in place of " so something like
::SETUP
::parenthesis is just to deliniate where it goes, it isn't
::actually in
::the code
set "var=(stuff goes here)"
call :TrimFunc "%var%",var
:TrimFunc
::the + are just to display the spacing otherwise I can't tell
echo beginning param1 is +%~1+
::code goes here for func
gotoEOF
::END SETUP
::NOTE the + characters aren't part of the actual value, just the
::display when I run this function
set "var=""a"""
::got +"a"+
will work but
set "var="a "
::got +"a+
::expected +"a +
set "var="a ""
::got +"a+
::expected +"a "+
set "var="a " "
::got +"a+
::expected +"a " +
set "var="a"
::got +"a",var+
::expected +"a+
will not work as expected. oddly,
set "var="a""
::got +"a"+
seemes to work despite not being escaped fully. Adding any spaces seems to disrupt this edge case.
Oddly enough I've tried doing:
set 'var="a"'
::got ++
::expected +"a"+
But I have no idea what changing ' to " actually does when its the one that contains the argument (not the ones that are supposed to be literal).
To see what would happen and
What I want:
Surely there must be some sort of universal escape character thing such that I can do this (assume the special character was *)
set *var=""something " "" " """*
call :TrimFunc "%var%",var
echo +%~1+
would net me
+""something " "" " """+
with no problems. In fact, why can't I have some universal escape character that can just be used to take in all the other characters inside it literally instead of the command line trying to process them? Perhaps I'm thinking about this wrong but this seems to be a recurring problem with weird inputs all over. I just want my vairbales, pipes and strings and all that to just STAY LITERAL WHEN THEY'RE SUPPOSED TO. I just want a way to have any input and not have any weird output, it should just treat everything literally untill I want it not to because it was enclosed by the mystical super special character that I just invented in my mind.
::noob rant
I don't see why this was never a thing. Whats preventing the makers of this highly useful language from simply creating a flag and some character that is never used to be the supremo escape character. Why do we need like 10 different ways of escaping characters? I should be able to programatically escape inputs if necessary, it should NEVER be the users job to escape their inputs, thats absolutely ridiculous and probably a violation of every good coding standard in existence
::END noob rant
Anyways. I'd be happy to be enlightened as to why the above is or isn't a thing. I just want to be able to use quotes IN A STRING (kinda important) And I can't comprehend why its not as simple as having one giant "treat these things as literals" flag that ALWAYS JUST WORKS(tm).
By the way, In case you're wondering why my function takes in the name of the variable it's writing to, I couldn't figure out how to get labels inside labels working without using delayed expansion. Using that means the variable I'm making is local not global so I use the name of the global variable to basically set it (using it's name) to the local value on return like this:
endlocal & set "%~2=%String%"
Feel free to yell at me on various things because I am 99% certain I'm doing something horribly syntactically wrong, have some bad misunderstandings or am simply way to naive to truly understand the complexity of this problem but to me it seems amazingly superfluous.
Why can't the last quote be used like the special character it is but any preceeding ones are taken literally (maybe depending upon a flag)
for example
set "var="a ""
why doesn't the ending two quotes act specially and the ones in between act literally? Can the CLI not tell where the line ends? Can it not tell the difference between the first and last quotes and the ones in between? This seems simple to implement to me.
As long as I can echo things properly and save their literal value from parameter to variable I'm happy.
Firstly, I'm don't really understand why you will want to use set "var=something" instead of set var=something, it doesn't seems to have difference.
Secondly, hope that helps, which I have (recently? IDK.) invented a method to deal with the annoying quotes. Hope this batch inspires or helps you to do sth similar.
#echo off
title check for length of string
color de
mode con: cols=90 lines=25
goto t
:t
set str=error
set /p str=Please enter four characters:
set len=0
goto sl
:sl
call set this=%%str:~%len%%%
if not "%this%" == "" (set /a len+=1 & rem debug" == "" (set /a len+=1
goto sl)
if not "%len%" == "4" (set n= not) else (set n=)
echo This is%n% a four character string.
pause >nul
exit
Which in your case:
if not "%var%" == "" (call :TrimFunc "%var%",var & rem debug" == "" (call :TrimFunc "%var%,var)
)
Hope that helps. Add oil~ (My computer doesn't support delayexpansion with unknown reason. Therefore, most of the codes are a bit clumsy.)
P.S.: If you are simply removing text and not replacing text, why not use set var=%var:string=%? If the string required is a variable too, then you can try this: call set var=%%var:%string%=%%

shorten every line in a text file by exactly 59 charaters then add a new shorter string in their place

For something so simple that can easily be done with find replace in notepad, I can't see why it is so hard to do in a command line as it is just one step in the entire procedure that I would like to get down to a single run. The output from the first part lists the local path to all the websites in the webserver as the each local path c:/ etc. every site has the same 59 characters before the part that matters.
To make this a usable link, I need to then add a different string in the same position as the old one with the correct http://. etc. to the balance of the line to make it a working hyperlink.
The final step needs to convert any single "\’s" that are left to a "/". Normally there is only one
All of this can be done in notepad++ using find and replace but it takes 3 runs to achieve the end result the original text file is nothing special, no skipped lines, everyone is identical in layout.
The same 59 characters need to be chopped off (it could even be by Number and not by comparing the text, just shorten by 59 characters if that is easier. The replacement text string is always exactly the same that just gets appended to each line. And for the final touch of replacing every \ with a / to make it fully web-compatible there is only one occurrence on each line.
I have seen many find and replace batch-files that seem to be overkill for such a simple task.
Take each line, count fifty nine characters forward, chop off the 59 and add in the replacement text in its place.
Then change the only backslash in the line to a forward slash and it’s done
Does anyone know a simpler easier way to do this
This uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
Place repl.bat in the same folder as the batch file or in a folder that is on the path.
Just change http://www.domain.com/ to what you need to prefix the lines with.
type "file.txt" | repl "\\" "/" | repl "^.{59}" "http://www.domain.com/" >"newfile.txt"
The two \\ are intentional as it is a regular expression.
#ECHO OFF
SETLOCAL
(
FOR /f "delims=" %%a IN (Q21495128.txt) DO (
SET "line=%%a"
CALL SET "line=%%line:\=/%%"
CALL SET "line=replacement text%%line:~59%%"
FOR /f "tokens=1*delims==" %%x IN ('set line') DO ECHO %%y
)
)>newfile.txt
GOTO :EOF
where Q21495128.txt was my test source file worked for me.

Batch file to read from filename and make directory

I have .txt files (1 or more) in a directory that I want my batch file to read their filename, get 20 characters starting from the 4th and creating a new directory in the folder. Here is my code:
for /f %%i in ('dir /b *.TXT') do (
set filename1=%%i
set folder1=%filename1:~4,20%
mkdir %folder1%
)
When I run this program the 1st time, I get a syntax not correct error for the line 3rd line (set folder1=....) and no folder is created. I tried running it a 2nd time and 2 folders were created (one named "~4" and one named "20"). On the 3rd run, the folder was correctly created! If I close the command prompt and open it again, it also needs to run 3 times before it creates the folder.
I've also tried using "for /r . $$i in (*.TXT) with no luck. As I understand, the problem is that the line with "set folder1=..." does not get the proper filename. I've also tried using %%~i or %%~ni, I've tried outputing the filename (which seems to always get the correct string) to a text file and then reading from that file, again with no luck. I don't know what else to try. Is it because %%i stores the file itself and not a string with the filename?
A sample file is named "REG_18004247K_20120208_A.TXT" and I want a folder to be created with the name "18004247K_20120208_A".
I am not at all familiar with batch programming (I'm only working with batch files for like 2 weeks) and I'm guessing the problem might be something really simple. Any help would be appreciated.
Kyriacos
%%i does stores a string with a filename. It is actually the only "variable" that works as expected here.
The key problem is that you are using environment variable substitution (of filename1 and of folder1) inside a loop, hoping that it will be expanded in each iteration of the loop.
However, environment variables are expanded before execution of the whole loop begins.
So, upon the first batch execution, filename1 is not defined and you get
an error, folder1 is not set, and you probably also see a folder
called %folder1% created.
However, the scripts defines filename1 at this time, and the second execution gets further to define folder1 correctly (although line 4 was
already expanded using the incorrect value and fun happens).
The third execution
finally gets to see the right value of folder1; but this would obviously not
work for more than one file, as the loop logic is dysfunctional.
This older answer explains this problem with great other examples and special cases.
Your batch can be fixed by setlocal enabledelayedexpansion at the beginning of the script, initializing the variables to empty strings before the loop, and switching to the !...! syntax when expanding them: !filename1:~4,20!, and !folder1!.
setlocal enabledelayedexpansion
for /r %%i in (*) do (
set filename1=%%i
set folder1=!filename1:~4,20!
mkdir !folder1!
)
Because ... delayed expansion takes some time to store actual variable.
!...! rather than %...% echoes fast allocating variables to DOS.

Is this batch file injection?

C:\>batinjection OFF ^& DEL c.c
batinjection.bat has contents of ECHO %*
I've heard of SQL injection, though i've never actually done it, but is this injection? Are there different types of injection and this is one of them?
Or is there another technical term for this? or a more specific term?
Note- a prior edit had C:\>batinjection OFF & DEL c.c(i.e. without ^%) and ECHO %1(i.e. without %*) which wasn't quite right. I have corrected it. It doesn't affect the answers.
Your example presents three interesting issues that are easier to understand
when separated.
First, Windows allows multiple statements to be executed on one line by
separating with "&". This could potentially be used in an injection attack.
Second, ECHO parses and interprets messages passed to it. If the message is
"OFF" or "/?" or even blank, then ECHO will provide a different expected
behavior than just copying the message to stdout.
Third, you know that it's possible to inject code into a number of
scriptable languages, including batch files, and want to explore ways
to recognize it so you can better defend against it in your code.
It would be easier to recognize the order in which things are happening
in your script if you add an echo statement before and after the one
you're trying to inject. Call it foo.bat.
#echo off
echo before
echo %1
echo after
Now, you can more easily tell whether your injection attempt executed at
the command line (not injection) or was executed as a result of parameter
expansion that broke out of the echo statement and executed a new statement
(injection).
foo dir
Results in:
before
dir
after
Pretty normal so far. Try a parameter that echo interprets.
foo /?
Results in:
before
Displays messages, or turns command-echoing on or off.
ECHO [ON | OFF]
ECHO [message]
Type ECHO without parameters to display the current echo setting.
after
Hmm. Help for the echo command. It's probably not the desired use of
echo in that batch file, but it's not injection. The parameters were
not used to "escape out" of the limits of either the echo statement or
the syntax of the batch file.
foo dog & dir
Results in:
before
dog
after
[A spill of my current directory]
Okay, the dir happened outside of the script. Not injection.
foo ^&dir/w
Results in:
before
ECHO is off.
[A spill of my current directory in wide format]
after
Now, we've gotten somewhere. The dir is not a function of ECHO, and is
running between the before and after statements. Let's try something
more dramatic but still mostly harmless.
foo ^&dir\/s
Yikes! You can pass an arbitrary command that can potentially impact
your system's performance all inside an innocuous-looking "echo %1".
Yes, it's a type of injection, and it's one of the big problems with batch files, that mostly it isn't a purposefully attac, most of the time you simple get trouble with some characters or word like OFF.
Therefore you should use technics to avoid this problems/vulnerabilitys.
In your case you could change your batch file to
set "param1=%*"
setlocal EnableDelayedExpansion
echo(!param1!
I use echo( here instead of echo. or something else, as it is the only known secure echo for all appended contents.
I use the delayed expansion ! instead of percent expansion, as delayed expansion is always safe against any special characters.
To use the delayed expansion you need to transfer the parameter into a variable and a good way is to use quotes around the set command, it avoid many problems with special characters (but not all).
But to build an absolutly secure way to access batch parameters, the way is quite harder.
Try to make this safe is tricky
myBatch.bat ^&"&"
You could read SO: How to receive even the strangest command line parameters?
The main idea is to use the output of a REM statement while ECHO ON.
This is safe in the way, that you can't inject code (or better: only with really advanced knowledge), but the original content can be changed, if your content is something like.
myBatch.bat myContent^&"&"%a
Will be changed to myContent&"&"4
AFAIK, this is know as command injection (which is one of types code injection attack).
The later link lists various injection attacks. The site (www.owasp.org) is an excellent resource regarding web security.
There are multiple applications of injection one can generalize as "language injection". SQL Injection and Cross Site Scripting are the most popular, but others are possible.
In your example, the ECHO statement isn't actually performing the delete, so I wouldn't call that injection. Instead, the delete happens outside of the invocation of the batinjection script itself.

Why BASIC had numbered lines? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why did we bother with line numbers at all?
I'm curious about why early versions of the BASIC programming language had line numbering like in:
42 PRINT "Hello world!"
The text editors back then had no line numbering?
EDIT: Yes, I know they are used for GOTOs, but why? I mean having labels was too computationally expensive?
Many microcomputers had a BASIC interpreter in ROM that would start upon bootup. The problem was that there was no text editor or file system to speak of. You had an interactive prompt to do everything through. If you wanted to insert a line of code, you just typed it, starting with the line number. It would insert it into the correct spot in you code. e.g:
>10 print "hello"
>30 goto 10
>20 print "world"
>list
10 PRINT "hello"
20 PRINT "world"
30 GOTO 10
>
(In that example > is the BASIC prompt)
If you wanted to erase a line, you would type something like ERASE 20.
Some really fancy systems gave you a line editor (i.e. EDIT 10)
And if you didn't plan your line numbers and ran out (how do I insert a line between 10 and 11?) some systems gave you a RENUM command which would renumber your code (and adjust GOTOs and GOSUBs appropriately).
Fun Times!
The original BASIC line numbering was actually an integral part of the language, and used for control flow.
The GOTO and GOSUB commands would take the line, and use it for control flow. This was common then (even though it's discouraged now).
They were used as labels for GOTO and GOSUB
Like this:
10 PRINT "HELLO WORLD"
20 GOTO 10
There were no named labels in some early BASIC versions
They were also required if you wanted to insert a line between 2 existing lines of code, because in the early days, you had no full text editors. Everything had to be typed in the "interactive" interpreter.
So if you typed:
15 PRINT "AND THE UNIVERSE"
The program would become:
10 PRINT "HELLO WORLD"
15 PRINT "AND THE UNIVERSE"
20 GOTO 10
When you ran out of line numbers, you could run a "renumbering" tool to renumber all lines in your program, but in the very early days of the Commodore 64 and other home computers, we didn't even have that, so you'd have to renumber manually. That's why you had to leave gaps of 10 or more in the line numbers, so you could easily add lines in between.
If you want to try out the Commodore 64 interpreter, check out this C64 emulator written in Flash: http://codeazur.com.br/stuff/fc64_final/ (no install required)
In BASIC, the line numbers indicated sequence.
Also, many older editors weren't for files, but simply lines ("line editors", e.g. ed, the standard editor). By numbering them this way, you knew which line you were working on.
A simple google reveals what wikipedia has to say about it:
Line numbers were a required element of syntax in some older programming languages such as GW-BASIC.[2] The primary reason for this is that most operating systems at the time lacked interactive text editors; since the programmer's interface was usually limited to a line editor, line numbers provided a mechanism by which specific lines in the source code could be referenced for editing, and by which the programmer could insert a new line at a specific point. Line numbers also provided a convenient means of distinguishing between code to be entered into the program and commands to be executed immediately when entered by the user (which do not have line numbers).
Back in the day all languages had sequence numbers, everything was on punched cards.
There was one line per card.
Decks of cards made up your program.
When you dropped the cards, you'd put them in a card sorter that used those sequence numbers.
And of course, they were referenced by control flow constructs.
On the C64, there wasn't even a real editor (built-in at least). To edit a part of the program, you'd do something like LIST 100-200, and then you'd only be able to edit those lines that were currently displayed on the screen (no scrolling upwards!)
They were labels for statements, so that you could GOTO the line number. The number of the statements did not necessarily have to match the physical line numbers in the file.
The line numbers were used in control flow. There were no named subroutines. You had to use GOSUB 60, for instance, to call the subroutine starting at line 60.
On your update, not all languages had labels, but all languages had line numbers at one time. At one time, everything was punch cards. BASIC was one of the very first interactive languages, where you could actually type something and have a response immediately. Line numbers were still the current technology.
Labels are an extra expense. You have to keep track of the correlation between the symbolic label and the code or data to which it refers. But if every line has a line number (and if all transfer of control flow statements always refer to the beginning of a line), then you don't need a separate symbol table.
Also keep in mind that original BASIC interpreters didn't need a symbol table for variables: There were 26 variables named A-Z. Some were sophisticated and had An-Zn. Some got very fancy and added a distinction between string, integer and floating point by adding "$" or "%" after the variable. But no symbol table was required.
IIRC, line numbers were mostly used as labels for GOTO and GOSUB statements, since in some (most?) flavors of BASIC there was no way to label a section of code.
They were also used by the editor - ie you said:
edit 100
to edit line 100.
As others have pointed out, these line numbers were used as part of subroutines.
Of course, there's a reason that this isn't done anymore. Imagine if you say GOTO 20 on line 10, and then later realize you need to write 10 more lines of code after line 10. All of a sudden, you're smashing up against 20 so you either need to shift your subroutine farther away (higher numbers) and change your GOTO value, or you need to write another subroutine that jumps farther in the code.
In other words, it became a nightmare of true spaghetti code and is not fun to maintain.
It was entered in on the command-line in many instances (or was, on my old Commodore 64) so there might not always have been a text editor, or if there was, it was quite basic.
In addition, you would need to do GOTOs and the like, as well as inserting lines in between others.
ie:
10 PRINT "HELLO"
20 GOTO 10
15 PRINT " WORLD"
where it would go in the logical 10 15 20
Some editors only had an "overwrite" mode and no "insert" mode. This made editing of existing code extremely painful. By adding that line-number feature, you could however patch existing code from anywhere within the file:
100 PRINT "Broken Code"
200 PRINT "Foobar"
...
101 patch the broken code
102 patch more broken code
Because line numbers didn't have to be ordered within the file.
Line numbers were a PART of the language, in some VERY early ones, even the OS was just these simple lines. ALL you had was one line at a time to manipulate. Try writing an accounting system using 1-4k program files and segmenting it by size to get stuff done. To edit you used the line numbers to tell what you were editing. So, if you entered like:
10 PRINT "howdy"
20 GOTO 10
10 PRINT "WOOPS"
15 PRINT "MORE WOOPS"
20
RUN
YOU WOULD GET:
WOOPS
MORE WHOOPS
The blank 20 would effectivly delete that line.

Resources