== was not expected at this time ( Batch File ) - if-statement

i'm making a simple .bat file that has some options. but when i use a space as a choice it says. == was not expected at this time. what did i do wrong ?
#ECHO off
title AutoMatic Program Install Beta v5 by eric
:ReturnToBaseLine
color 0a
cls
echo Made By The Amazing
echo[
echo ____ _ ________ ___
echo / __/___(_)___ /_ __/ / ___ / _ \_______ ___ ___ _ ___ ____
echo / _// __/ / __/ / / / _ \/ -_) / // / __/ -_) _ `/ ' \/ -_) __/
echo /___/_/ /_/\__/ /_/ /_//_/\__/ /____/_/ \__/\_,_/_/_/_/\__/_/
echo[
Echo[
Echo .-. .-. .-. .-. .-. .-. .-. .-. .-.
Echo .' `._.' `._.' `._.' `._.' `._.' `._.' `._.' `._.' `.
echo[
Echo Wilt u Microsoft Office Installeren(M) of een Anti-Virus Progamma(A) ?
echo[
echo Of Wilt u Overige Software Instalereren(O) ?
echo[
echo Afsluiten(X)
echo[
Echo .-. .-. .-. .-. .-. .-. .-. .-. .-.
Echo .' `._.' `._.' `._.' `._.' `._.' `._.' `._.' `._.' `.
echo[
echo[
set /p choice=Keuze :
if not '%choice%'=='' ECHO "%choice%" Is niet een geldige optie
if '%choice%'=='M' goto Office
if '%choice%'=='m' goto Office
if '%choice%'=='A' goto Anti
if '%choice%'=='a' goto Anti
if '%choice%'=='O' goto Overig
if '%choice%'=='o' goto Overig
if '%choice%'=='X' exit
if '%choice%'=='x' exit
Pause
Goto :ReturnToBaseLine

Space is a default separator, so batch sees if '[separator]'==''
To enclose a string containing spaces and other separators, use Rabbits Ears thus: "%choice%"
Also : you can use the /i switch wit if to make the comparison case-insensitive.

For paths enclosed in double quotes use
if [%1]==[]
instead of
if "%1"==""
which will fail when you try calling your try.bat with a quoted param and spaces
try "hello world"
The error given if you use if "%1"=="" is: "== was not expected
Using [] or any other delimiter that isn't part of the JS language (don't use quote, double quote, (, =, +, {,

Related

Unicode characters stuffing regex quantifiers in perl 5 [duplicate]

This question already has answers here:
Perl regular expression matching on large Unicode code points
(2 answers)
Closed 2 years ago.
I'm new to perl and having troubles with regex quantifiers on multibyte unicode characters (utf-8) with perl 5, I expect them to count only for one character but they count for as many bytes composing them.
For example, I expect .{1} to match é and .{2} to not match, but I see that :
$ echo 'begin é end' | perl -wnl -e '/begin .{1} end/s and print'
$ echo 'begin é end' | perl -wnl -e '/begin .{2} end/s and print'
begin é end
It is clearly due to "é" being a multibyte character because when I replace it by a simple "e" I get what I expect :
$ echo 'begin e end' | perl -wnl -e '/begin .{1} end/s and print'
begin e end
$ echo 'begin e end' | perl -wnl -e '/begin .{2} end/s and print'
Using some character set modifier (/d /u /a and /l) does not change anything.
When I use another PCRE regex tool it works :
regex101 : https://regex101.com/r/a1Lb9g/1/
php 7 (with u modifier to enable unicode support) :
$ echo 'begin é end' | php7 -r 'var_dump(preg_match("/begin .{1} end/su", file_get_contents("php://stdin")));'
Command line code:1:
int(1)
My TTY uses UTF-8 charset, "é" is encoded c3a9 :
$ echo 'begin é end' | xxd
00000000: 6265 6769 6e20 c3a9 2065 6e64 0a begin .. end.
$ echo 'begin é end' | base64
YmVnaW4gw6kgZW5kCg==
I have tested on several OS and perl versions and I see the same behavior everywhere :
This is perl 5, version 22, subversion 1 (v5.22.1) built for i686-msys-thread-multi-64int (Windows 7)
This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-msys-thread-multi (Windows 10)
This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux-gnu-thread-multi (Ubuntu 16.04)
How to make perl regex quantifiers counting unicode characters for one ?
You need to tell Perl that the input is encoded in UTF-8. That's done by -CI. Add O to encode the output, too:
echo 'begin é end' | perl -CIO -wnl -e '/begin .{1} end/s and print'
begin é end

How to use sed to replace u'sometext' with 'sometext'

I have a file with text in it I simply want to strip off the leading u from all instances of u'sometext' so that it leaves 'sometext'. I haven't been able to figure out how to get sed to match on u' and replace with '.
Sed command I though would work:
echo ['a', u'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null'] | sed "s/u'/'/g"
output:
[a, uupdate for microsoft office 2013 (kb4022166) 32-bit edition, unknown, null]
what I wanted:
['a', 'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null']
More examples of what is in the file:
"[u'cpe:/o:microsoft:windows_7::sp1:x64-enterprise', u'cpe:/a:adobe:acrobat:11.0.19']"
What I would like to have:
"['cpe:/o:microsoft:windows_7::sp1:x64-enterprise', 'cpe:/a:adobe:acrobat:11.0.19']"
Try, if possible, with something like this:
echo "['a', u'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null']" | sed "s/u'/'/g"
OUTPUT:
['a', 'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null']
It seems that it is not taking well the complete string but assuming it as several ones.
You will need to use word boundaries, denoted with the special character \b which goes immediately before the first thing to be matched on a boundary
$ echo "[u'a', u'hello']" | sed "s/\bu'/'/g"
['a', 'hello']
$ echo "[u'a', u'hello', u'version 7-u']" | sed "s/u\('[^']*'\)/\1/g"
['a', 'hello', 'version 7-u']
$ echo "['a', u'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null']" | sed "s/u\('[^']*'\)/\1/g"
['a', 'update for microsoft office 2013 (kb4022166) 32-bit edition', 'unknown', 'null']
$ echo "[u'cpe:/o:microsoft:windows_7::sp1:x64-enterprise', u'cpe:/a:adobe:acrobat:11.0.19']" | sed "s/u\('[^']*'\)/\1/g"
['cpe:/o:microsoft:windows_7::sp1:x64-enterprise', 'cpe:/a:adobe:acrobat:11.0.19']
Note though that both the above and the currently accepted answer would fail if you can have a u at the end of a single-quote-delimited string earlier in the line. e.g.:
$ echo "['u', 'a']" | sed "s/u\('[^']*'\)/\1/g"
['', 'a']
$ echo "['u', 'a']" | sed "s/\bu'/'/g"
['', 'a']
so, assuming that is an issue, we can use a more robust approach with awk (in this case using GNU awk for multi-char RS and RT):
$ echo "['u', 'a']" | awk -v RS="'[^']*'" -v ORS= 'RT{sub(/u$/,"")} {print $0 RT}'
['u', 'a']
$ echo "[u'a', u'hello', u'version 7-u']" | awk -v RS="'[^']*'" -v ORS= 'RT{sub(/u$/,"")} {print $0 RT}'
['a', 'hello', 'version 7-u']

POSIX sh: find and replace with function

In JavaScript, you can do:
someComplexProcessing = (wholeMatch, group1, group2, index, mystr)=> replacement...
mystr.replace(/some.* regex(with) multiple (capture groups)/g, someComplexProcessing)
eg.
const renderTemplate = (str, env)=> str.replace(/{{(.*?)}}/g, (_, name)=> env[name])
renderTemplate('{{salut}} {{name}}!', {salut: 'Hi', name: 'Leo'}) // "Hi Leo!"
What is the best POSIX compatible, generic, variant?
- reusability # eg. a function taking regex, processingFunction, and input, etc - that I could but in my .shellrc/source lib.sh or similar and reuse
- multiline # eg. if "uppercase everything between {{ and }}", `a {{b\nc}}` -> `a B\nC`
- no escape gotchas # eg. it shouldn't break if input, replacement, or regex contains special characters
- POSIX compatible # eg. running it under `docker run --rm -it alpine sh`, etc
- using regex # eg. perl regex seems like the most prominent one, please note differences from it if other is used
meriting:
- no/less dependencies # eg. as portable as possible
- multiple capture groups
- performance
- security # related to no escape gotchas, eg. ok with untrusted input
I've found a couple solutions for bash, and a few compatible edge-case solutions, though none that does it all anywhat close to the simplicity js' .replace provides. Ultimately, I want to program without thinking too much on implementation details/gotchas, and without bringing in 100's of MB (mostly to alpine container, but also using ubuntu/OSX), thereby trying to build up a library of portable, posix-compatible snippets, functions and patterns.
An uneffective, input somewhat escaped (assumes no \r) (but not regex input escaped), solution, with only one capture group (middle). Though portable (only uses tr and sed (and printf, -z empty string check). (possibly possible to change the sed parts to something generally perl regex compatible)
lib.sh:
#!/usr/bin/env sh
multiline_substitute_with_fn () {
sub_start="$1"; shift; fn_name="$1"; shift; sub_end="$1"; shift; left="$(cat)";
# uppercase () { cat | tr 'a-z' 'A-Z'; }; echo 'Hello [there]!' | multiline_substitute_with_fn '\[' uppercase '\]'
# make single-line, sanitize input against _SUB(START|END)_, a\ra {{echo "b\rb"}} c {{echo d}} e
left="$(echo "$left" | tr '\n' '\r' | sed 's/_SUB/_ASUB/g')"
while [ ! -z "$left" ]; do
left="$(echo "$left" | sed "s/$sub_start/_SUBSTART_/")" # a\ra _SUBSTART_echo "b\rb"}} c {{echo d}} e
printf '%s' "$(echo "$left" | sed 's/_SUBSTART_.*//' | sed 's/_ASUB/_SUB/g' | tr '\r' '\n')" # a\na
lefttmp="$(echo "$left" | sed 's/.*_SUBSTART_//' | sed "s/$sub_end/_SUBEND_/")" # echo "b\rb"_SUBEND_ c {{echo d}} e
if [ "$lefttmp" = "$left" ]; then left=''; break; fi
left="$lefttmp"
middle="$(echo "$left" | sed 's/_SUBEND_.*//' | tr '\r' '\n')" # echo "b\nb"
[ ! -z "$middle" ] && printf '%s' "$(echo "$middle" | $fn_name | sed 's/_ASUB/_SUB/g')" # b\nb
left="$(echo "$left" | sed 's/.*_SUBEND_//')" # c {{echo d}} e
done
}
usage:
cat file | multiline_substitute_with_fn 'start regex' processingFunction 'end regex'
eg. usage:
#!/usr/bin/env sh
. ./lib.sh # load lib
uppercase () { cat | tr 'a-z' 'A-Z'; };
echo 'Hello [there]!' | multiline_substitute_with_fn '\[' uppercase '\]'
# -> Hello THERE!
eval_template () { # not "safe" in terms of eval
# echo 'a\na {{echo "b\nb"}} c {{echo d}} e' | eval_template # -> 'a\na b\nb c d e'
# hello=hi; echo '{{=$hello}} there' | eval_template # -> {{echo "$hello"}} there -> 'hi there'
fn () {
middle="$(cat)"
case "$middle" in =*) middle="echo \"${middle#=}\"" ;; *);; esac # '=$a' -> 'echo "$a"'
eval "$middle"
}
cat | multiline_substitute_with_fn '{{' fn '}}'
}
eval_template <<-EOF
a
a {{echo "b
b"}} c {{echo d}} e
EOF
# -> a
# a b
# b c d e'
echo '{{=$salut}} {{=$name}}!' > my.template
salut=Hi; name="Leo Name";
cat my.template | eval_template
# Hi Leo Name!

Bash number extraction from different places in STDOUT

Here is the output given by speedtest-cli: (personal information redacted with test data)
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from ------ (xxx.xxx.xxx.xxx)...
Selecting best server based on latency...
Hosted by ------- (------, --) [15.00 km]: 50.00 ms
Testing download speed........................................
Download: 60.00 Mbit/s
Testing upload speed..................................................
Upload: 10.00 Mbit/s
Where I want the output to be a comma separated line of ping, dl, ul:
50.00, 60.00, 10.00
I have been working on a solution and have come up with this:
speedtest-cli | sed -n "5p;7p;9p" | grep -oE "[[:digit:]]{1,}" | tr '\n' ,
Which outputs:
15,00,50,00,60,00,10,00,
Which is close to what I want. Except that it is including the distance (15.00km) from the 5th line and splitting based on . as well. Is there a better way to do this using awk or something similar?
Using awk you can do:
speedtest-cli | awk -v ORS=', ' '/^(Hosted|Download|Upload)/{print $(NF-1)}'
50.00, 60.00, 10.00,
To use newline instead of trailing , use:
speedtest-cli | awk -v ORS=', ' '/^(Hosted |Download:)/{print $(NF-1)}
/^Upload:/{printf "%s%s", $(NF-1), RS}'
50.00, 60.00, 10.00
If your grep supports PCRE (-P), you can do:
% grep -Po '^(Hosted|Download|Upload).*:\K [^ ]+' file.txt | tr '\n' ','; echo
50.00, 60.00, 10.00,
So:
speedtest-cli | grep -Po '^(Hosted|Download|Upload).*:\K [^ ]+' | tr '\n' ','; echo

paramiko stdout show nothing with regular expression?

I try to use paramiko to list all TCP ports used on a compute. I found a good bash command here:
netstat -ant | sed -e '/^tcp/ !d' -e 's/^[^ ]* *[^ ]* *[^ ]* *.*[\.:]\([0-9]*\) .*$/\1/' | sort -g | uniq
This command works perfectly when I directly enter it in putty. However, when use it with paramiko, no output is shown.
Here is the sample code:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='demo', password='password')
command = "netstat -ant | sed -e '/^tcp/ !d' -e 's/^[^ ]* *[^ ]* *[^ ]* *.*[\.:]\([0-9]*\) .*$/\1/' | sort -g | uniq"
stdin, stdout, stderr = ssh.exec_command(command)
print stdout.read()
If I change the command as follow, the stdout do show the result, but this is not what I want. So I guess this is probably a regular expression issue with paramiko. Any idea?
command = "netstat -ant | sed -e '/^tcp/ !d'"
'\1' is same as '\x01'. You should escape \1.
>>> '\1'
'\x01'
>>> print '\1'
>>> '\\1'
'\\1'
>>> print '\\1'
\1
>>> r'\1'
'\\1'
>>> print r'\1'
\1
Using raw string(r'...') solve your problem:
command = r"netstat -ant | sed -e '/^tcp/ !d' -e 's/^[^ ]* *[^ ]* *[^ ]* *.*[\.:]\([0-9]*\) .*$/\1/' | sort -g | uniq"