You are not logged in.
Hi all - great site!
Trying to perform validation /bounds check / sanity check on user input before writing to a file to be processed by another script.
The input should only contain English alpha or numeric chars, heres an example of good input:
blahblahlbah201902210000201902200000
Note: if it's "easier" I can split the alpha and numeric piece up and validate separately - in fact I may do that - as the fields that are numeric should ONLY be numeric (0-9), the first part can be alpha or numeric.
Here's the type of issue I want to catch - bad input:
blahblahblahblah20190221003020190@221200
So - using findstr I can explicitly look for special chars such as: findstr "@ . # $ % ^ & * ( ) ! ~ < > : ; '[ ] { } |"
BUT, then I have to list every special char.... Doable, but not clean.
What I prefer to do conceptually is:
find input that contains any characters OTHER than (0-9) or (a-z) or (A-Z) or (-) or (_)
if %errorlevel% EQU 0 GOTO BADINPUT
I tried a few different syntax of findstr, but can't get it to work as I wish. I'll keep trying - but any help would be greatly appreciated.
TIA!
Gary
Offline
If you have an well defined set of "good" characters, then your best bet would be to use an inverse character class.
Ref: https://ss64.com/nt/findstr.html
[class] Character class: any one character in set
[^class] Inverse class: any one character not in set
So, something along these lines...
set /p ="yourinput" <nul | findstr /i "[^a-z0-9_-]" >nul
if errorlevel 1 (
echo:looks good
) else (
echo:bad characters
)
cmd | *sh | ruby | chef
Offline
Hi. Thanks for the prompt reply. I tried that inverse class with no luck. I tried various combinations of the inverse class as well as "/v" , different patterns, wildcards, syntax, etc. Give me a few mins - I'll post an example - and try your example - maybe I had a typo somewhere.
Thanks!
Gary
Offline
No love....
My test script and my output below. The errorlevel is always 0 regardless if the string contains special chars or not, and if I use inverse class or not. FWIW, I never touched powershell before and got this working there in 5 mins - as it functions like I would expect it to. Some will then ask - why not use PS? Good question... I have this entire process written in CMD shell that's pretty decent I think... I mostly did it to prove a point to others that mock the CMD shell, 'cause they don't know about 95% of what can be accomplished with it. TIA! - Gary
@echo off
echo -------- LOOK FOR NUMBERS --------
echo 123123 | findstr "[0-9]"
echo errorlevel is: %errorlevel%
echo.
echo -------- LOOK FOR NON NUMBERS --------
echo 123123 | findstr "[^0-9]"
echo errorlevel is: %errorlevel%
echo.
echo -------- LOOK FOR NUMBERS --------
echo 123123.!@ | findstr "[0-9]"
echo errorlevel is: %errorlevel%
echo.
echo -------- LOOK FOR NON NUMBERS --------
echo 123123.!@ | findstr "[^0-9]"
echo errorlevel is: %errorlevel%
C:\TEMP>test-findstr.cmd
-------- LOOK FOR NUMBERS --------
123123
errorlevel is: 0
-------- LOOK FOR NON NUMBERS --------
123123
errorlevel is: 0
-------- LOOK FOR NUMBERS --------
123123.!@
errorlevel is: 0
-------- LOOK FOR NON NUMBERS --------
123123.!@
errorlevel is: 0
Offline
I will read findstr docs again. Starting to wonder if I have to use a for loop or substring thingy to evaluation each character of the string individually?
Offline
Hello again,
I don't think the inverse class is working correctly. I copied a basic example from the findstr page on this site, and fed it a few more examples. Either I am not interpreting something correctly, or inverse is broken.
I THINK it works as expected when using files vs. redirection! Tested a few times and this seems to be the case. Maybe CRLF (or something?) is appended at the end of string during redirection, and that is what findstr is picking up?
Echo 12@6 |FindStr /R "[0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more numeric characters
12@6
errorlevel is: 0
The string contains one or more numeric characters
* Works as expected
Echo 12@6 |FindStr /R "[^0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more non numeric characters
12@6
errorlevel is: 0
The string contains one or more non numeric characters
* Works as expected
Echo 1256 |FindStr /R "[0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more numeric characters
1256
errorlevel is: 0
The string contains one or more numeric characters
* Works as expected
Echo 1256 |FindStr /R "[^0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more non numeric characters
1256
errorlevel is: 0
The string contains one or more non numeric characters
**** FAILED! String only has numerics - unless CRLF (or something?) is appended at the end during redirection? I THINK it works as expected when using files vs. redirection! Tested a few times and this seems to be the case.
Echo abcd |FindStr /R "[0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more numeric characters
errorlevel is: 1
* Works as expected
Echo abcd |FindStr /R "[^0-9]"
echo errorlevel is: %errorlevel%
If %ERRORLEVEL% EQU 0 echo The string contains one or more non numeric characters
abcd
errorlevel is: 0
The string contains one or more non numeric characters
*Works as expected
Offline
You will never get a correct ERRORLEVEL value from a piped command, like this one:
command1 | command2
This is because the returned ERRORLEVEL is not from the second command, but from the cmd.exe process used to run the second command. Besides, the pipe inserts blank spaces in the string passed to the second command.
You must use FINDSTR command over a file:
@echo off
echo -------- LOOK FOR NUMBERS --------
echo 123123> file.txt
findstr "[0-9]" file.txt
echo errorlevel is: %errorlevel%
echo/
echo -------- LOOK FOR NON NUMBERS --------
findstr "[^0-9]" file.txt
echo errorlevel is: %errorlevel%
echo/
echo -------- LOOK FOR NUMBERS --------
echo 123123.!@> file.txt
findstr "[0-9]" file.txt
echo errorlevel is: %errorlevel%
echo/
echo -------- LOOK FOR NON NUMBERS --------
findstr "[^0-9]" file.txt
echo errorlevel is: %errorlevel%
Antonio
Offline
Thanks. I think I have a solution:
This: echo 123| findstr /r "[^0-9]"
NOT:
echo 123 | findstr /r "[^0-9]".
Spaces on trailing end of the string (before the pipe symbol) are interpreted as part of the string. Which makes perfect sense, but not the natural syntax....
Still testing, but I think this will work. Passed the first set of tests, which until not have failed.
As far as the errorlevel coming from the cmd or the 2nd command , I can't speak to that. As indicated, when I use the pipe symbol immediately following the string (no space) it get the behavior I want.
Thanks!
Gary
PS: writing to files is a last resort for me. I avoid any I/O not 100% necessary, so I'll find a way to avoid it whenever I can.
Offline
I refer you to my solution. The reason I used "set /p" instead of "echo" is because it's very difficult to quote properly using "echo", and also it's very easy to send a trailing space when piping an "echo", which I believe is the problem you encountered.
set /p ="yourinput" <nul | findstr /i "[^a-z0-9_-]" >nul
"set /p" has two nice effects -- you can quote strings without including the quotes in them, and the quoted string is what is sent to a pipe.
@Aacini ... I don't think it's necessary to use findstr with a file, the errorlevel in "something | findstr" will always come from the "findstr" (as far as I know).
Last edited by bluesxman (25 Feb 2019 14:06)
cmd | *sh | ruby | chef
Offline