I am building a Username and Password function for a batch file, and I have the system to read from 2 text files, Uname and Pass, and find the usernames and passwords, but the system is pulling any password listed in Pass. How can I read the line the username is on, set the password to only accept the corresponding line in the Pass text file?
FOR /F "tokens=* delims=" %%x in (Users.txt) DO IF '%uname%'=='%%x' goto AdmCont
rem FOR /F "tokens=* delims=" %%x in (Pass.txt) DO IF '%code%'=='%%x' goto AdmCont
Here is a simpler solution:
for /f "delims=: tokens=1,2" %A IN ('findstr /n "%uname%" Users.txt') do ( #set "number_of_line=%A" && #set "_uname=%B" )
Or, using find instead of findstr (quite complicated):
for /f "eol=- delims=[] tokens=1-2" %A IN ('find /n "%uname%" Users.txt') do ( #set "number_of_line=%A" && #set "_uname=%B" )
As in your post you have requested batch file code (you have double percent signs (%%)) you can double the percent-signs of the variables.
Let me explain my code:
In both two loops, we parse output of commands. You should know the command-output-format and why using findstr is much simpler.
findstr
We use /n option with findstr which tells it to echo the line that found string specified.
After /n option, we specify string that should be searched in specified after file.
After that, we specify the file we want to search the specified string.
The output will be:
%line_number%:%content_of_line%
So, we parse it saying:
DON'T PARSE : symbol into token with delims=: option!
Access the line_number with %(%)A and content_of_line with %(%)B using tokens=1,2 option.
Well known: specify variable letter add IN, then command to be parsed and set to variables number of line and its content.
find
We use /n option with find which tells it to echo the line that found string specified.
After /n option, we specify string that should be searched in specified after file.
After that, we specify the file we want to search the specified string.
The syntax is quite similar, but the output is completely different!:
---------- %FILENAME_SPECIFIED_WITH_CAPITAL_LETTERS%
[%line_number%]%line_content%
So, here:
We ignore lines starting with - with eol=- option.
We don't parse [] symbols into tokens with delims=[].
We want to access line_number with %(%)A and line_content with %(%)B, so, we add tokens=1,2 option.
Then, continuing as above (well known).
For better understanding how these commands work, I suggest you to open a new cmd window and type:
for /?
find /?
findstr /?
Try some examples of yours with find and finstr to completely understand how they work.
Some interesting references for further reading:
https://ss64.com/nt/findstr.html
https://ss64.com/nt/for_cmd.html
https://ss64.com/nt/find.html
Related
I am reading a values from the xml file using batch ,
values are like Age="18"
When the value is extracted i don't want the double quotes
for /f "tokens=2 delims= " %%b in ('type <file_name> ^| FIND "info" ) do (
echo %%b
set string =%%b
string = Age="18" ( getting error here)
in the info tag
<info Name="xxx" Age="18"></info>
i need only the value 18 to be stored in a variable
Need assistance
This task can be done with:
for /F "tokens=5 delims==> " %%I in ('%SystemRoot%\System32\findstr.exe /R /C:"<info .* Age=\"[0123456789][0123456789]*\"" "XmlFile.xml"') do echo %%~I& set "string=%%~I"
FOR executes in this case in background one more command process with %ComSpec% /c and the command line between ' appended as additional arguments. So executed is in background with Windows installed to C:\Windows:
C:\Windows\System32\cmd.exe /c C:\Windows\System32\findstr.exe /R /C:"<info .* Age=\"[0123456789][0123456789]*\"" "XmlFile.xml"
FINDSTR runs a case-sensitive regular expression search for a line containing <info containing the attribute Age and the attribute value being a number. The found line is output to handle STDOUT (standard output) of the background command process captured by FOR.
After started cmd.exe closed itself after findstr.exe terminated, FOR processes the captured output line by line with skipping empty lines.
The line is split up into substrings using = and > and space as string delimiters because of delims==> . The fifth substring is the value of attribute Age enclosed in double quotes which is assigned to the specified loop variable I because of tokens=5. The double quotes are removed because of using modifier %~I.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
findstr /?
for /?
set /?
Instead of choosing the 2nd token with as the delimiter, you probably want the 4th token using the " as a delimiter:
#For /F Tokens^=4^ Delims^=^" %%G In ('^""%__AppDir%find.exe" /I "<info "^<"filename.txt"^"') Do #Set "age=%%G"
You may also wish, for robustness, to match a more unique pattern. You can do that by choosing findstr.exe instead of find.exe:
#For /F Tokens^=4^ Delims^=^" %%G In ('^""%__AppDir%findstr.exe" /IR "<info\ Name=\"[a-Z]*\"\ Age=\"[0-9]*\">" "filename.txt"^"') Do #Set "age=%%G"
Please note that the pattern I have used for the age, allows for superscript digits. However, this scenario is unlikely ever to be encountered, in your actual case, so I figured that this pattern should suffice.
I am trying to create a Volume Shadow copy from a BATCH file but have encountered a issue I am unable to explain.
When running the below command:
FOR /F "tokens=3" %%A IN ('"WMIC shadowcopy call create ClientAccessible,"C:\""^| FIND /I "ShadowID"') DO SET ID=%%A
I receive the below error
Invalid format. Hint <paramlist> = <param> [, <paramlist>].
but if I replace FIND with FINDSTR and remove the quotes from around the word I am searching for it seems to work correctly.
FOR /F "tokens=3" %%A IN ('"WMIC shadowcopy call create ClientAccessible,"C:\""^| FINDSTR /I ShadowID') DO SET ID=%%A
Can anyone explain to me why the first command will not work or what I am overlooking to make the first command work?
Yes, I know there are many other, including better, ways to achieve what I am wanting to do but for now I am just trying to better understand what I am missing here.
Thanks greatly
There are two problems in your code:
You stumbled upon a strange behaviour of FOR /F: it does not only remove the single quotes (apostrophies, '') around the command to parse, it also removes enclosing quotation marks if the first and last character of the remaining string are " both1, so the command line that is actually tried to be executed is WMIC shadowcopy call create ClientAccessible,"C:\""| FIND /I "ShadowID, which is invalid of course.
The WMIC command line is enclosed in quotation marks, so even if the above issue was not there, your code would fail, because the command interpreter tries to find a command or program named "WMIC shadowcopy call create ClientAccessible,", which does not exist of course.
So the corrected command line is:
FOR /F "tokens=3" %%A IN ('WMIC shadowcopy call create ClientAccessible^,"C:\" ^| FIND /I "ShadowID"') DO SET "ID=%%A"
Note that you need to escape the , herein (similar to the pipe).
1) You can affirm that by trying the command line FOR /F "tokens=3" %%A IN ('"WMIC" shadowcopy call create ClientAccessible^,"C:\" ^| FIND /I "ShadowID"') DO SET "ID=%%A", which fails, and FOR /F "tokens=3" %%A IN ('^""WMIC" shadowcopy call create ClientAccessible^,"C:\" ^| FIND /I "ShadowID"^"') DO SET "ID=%%A", which works because there are additional "" put around (they are escaped like ^" so that the command line does not need to be altered in terms of escaping; you could also state the " literally, but then you needed to unescape the , and the |).
In addition, I recommend to nest another FOR /F loop inside yours, because WMIC returns Unicode text, which could leave artefacts (orphaned carriage-return characters) when being parsed by FOR /F (as it expects ANSI text); an additional parsing phase eliminates such noise:
FOR /F "tokens=3" %%A IN ('WMIC shadowcopy call create ClientAccessible^,"C:\" ^| FIND /I "ShadowID"') DO FOR /F "delims=" %%B in ("%%A") DO SET "ID=%%B"
This method is credited to dbenham -- see his answer to Why is the FOR /f loop in this batch script evaluating a blank line? and also his external article WMIC and FOR /F : A fix for the trailing <CR> problem.
This is happening because the output of the WMCI command is in unicode. See this post Editing WMIC output format
i currently have this command for a batch file
for /F "skip=1 tokens=1 delims=\n" %i in (stats.txt) do echo %i
with the contents of stats.txt being
Title = Subaru's Great Rehab Strategy
URL = http://dynasty-scans.com/chapters/subarus_great_rehab_strategy
Tags = Subaru x Tsukasa[|]Yuri[|]
No. of Pages = 3
^ NOTE: the final line is actually blank
the idea of the line of code is to return the 2nd line with URL. the end goal would be that i would run this line in some sort of loop going though a series of ~12000+ stats.txt files and collecting all the URL lines into a single file
but when i run the command i get this
as you can see it has skipped the first line but it's cutting off where the n in dynasty and outputting the last 3 lines.
now if i remove delims=\n i get the same 3 lines but i don't get the first word before the space which seems to indicate that the value of delims is what splits a line into "tokens" which then i just grab the first one (and space must be the default)
when i go into notepad++, open the Find and Replace Dialog, turn Search Mode to extended and look for "\r\n" i get taken to the end of each line which is why i chose delims to be \n assuming this would then make the entire line one token
So my question is How can i get all of the 2nd line only of my stats.txt file?
The for /f loop already treats the carriage return and / or line feed as an end-of-line. No need to specify it as a delimiter. With delims=\n you're actually saying that all literal backslashes and letter n's should be treated as token delimiters. If you want the whole line, what you want is "skip=1 delims=".
Just out of habit, when reading the contents of a file with a for /f loop, I find it useful to enable usebackq just in case the filename / path contains a space or ampersand. That allows you to quote the filename to protect against such potential treachery.
#echo off
setlocal
for /F "usebackq skip=1 delims=" %%I in ("stats.txt") do if not defined URL set "URL=%%~I"
echo %URL%
Put into context, to use this to read many files named stats.txt and output the URLs into a single collection, enclose the whole thing in another for loop and enable delayed expansion.
#echo off
setlocal
>URLs.txt (
for /R %%N in ("*stats.txt") do (
for /F "usebackq skip=1 delims=" %%I in ("%%~fN") do (
if not defined URL set "URL=%%~I"
)
setlocal enabledelayedexpansion
echo(!URL!
endlocal
set "URL="
)
)
echo Done. The results are in URLs.txt.
If you want to strip the "URL = " from the beginning of each line and keep only the address, you could try changing your for /F parameters to "usebackq skip=1 tokens=3" if all the files follow the same format of URLSpace=Spacehttp://etc.. If you can't depend on that, or if any of the URLs might contain unencoded spaces, you could also change echo(!URL! to echo(!URL:*http=http!
You don't need to use a FOR /F loop, you can also read it with a SET /P
setlocal EnableDelayedExpansion
< stats.txt (
set /p line1=
set /p URL_Line=
)
echo(!URL_Line!
Try this from the command line:
(for /F "tokens=1* delims=:" %i in ('findstr "URL" stats*.txt') do echo %j) > output.txt
the idea ... is to return the 2nd line with URL
If you want to insert this line in a Batch file, just double the percent signs.
Try this from the prompt:
(for /f "tokens=1*delims=]" %a in ('find /v /n "" *.csv^|findstr /l /b "[2]"') do #echo %b)>u:\r1.txt
Where - I used *.csv for testing (substitute your own filemask) and I used u:\r1.txt for the result - substitute as seems fit (but don't output to a file tat fits your selected filemask !)
It works by prefixing each line in each file with a bracketed number [n] (find - /n=and number /v lines that do not match "" - an empty string); then selecting those lines that /l - literally /b at the beginning of the line match "[2]".
The result is all of the second-lines of the files, preceded by the literal "[2]". All we need to do then is tokenise the result, first token up to delimiter "]" will be "[2" assgned to %%a and remainder-of line (token *) will be assigned to %%b
Have you tried
for /F "skip=1 tokens=1 delims=\n" %i in (stats.txt) do echo %i && goto :eof
I haven't tested it as I don't have access to a Windows machine at the moment, but that should exit the for-loop after the first iteration, which is what you want.
So I am trying to create batch script that does a findstr of two variables. I am reading from a specific file where I need the variables from.
The variables I need are
NetPath=
NetPathmed=
And my goal is to use the two variables to do a network map drive. In the first findstr I need everything after the NetPath= and in the second I need just a specific amount of data from the string. A normal NetPathMed looks like this
NetPathmed=\\**IPaddress**:C:\folder\file.
I just need the IP address
For example the batch I created looks like this
cd: C:\folder\
set var1="findstr 'NetPath=' file.ini"
for /f "tokens=1,2 delims== " %%a in ("%var1%") do set net=%%a&set path=%%b
Set var2= "findstr 'NetPathMed' opsetup.ini"
for /f "tokens=1,2,3 delims==/ " %%c in ("%var2%") do set net=%%c&set path=%%d &set net=%%e
net use var1(driveletter) \var2(IPaddress)\network folder /persistent:yes
cd C:\folder\
set var1='findstr "NetPath=" file.ini'
for /f "tokens=1,* delims==" %%a in (%var1%) do set var1=%%b
Set var2='findstr "NetPathMed" opsetup.ini'
for /f "tokens=2,3 delims=\:" %%c in (%var2%) do ECHO elements %var1% %%c %%d: /persistent:yes
Well - fixed a bit. Very difficult to tell where the elements you are extracting from your files actually are and which you wish to assemble into your command.
Made worse by your using 'NetPathMedin your code butNetPathmedin the data line you have given. If you don't use the/iswitch,findstr` is case-sensitive.
Other errors:
cd: should not have a :.
The command within the parentheses of the for /f should be enclosed in SINGLE quotes. FINDSTR likes "double quotes"
I couldn't tell whether you wanted the data to be placed in var1 and var2 or what - an example of the relevant contents of the two files and the required command to be generated would have been helpful.
I chose to assign all of the text after the = in the selected line from the first file into var1 (because that's what you said)
The first part in %%a is token1 = NetPath (not used) and the second token (*=the rest of the line) appears in the next metavariable (%%b)
Similarly, parsing the EXACT DATA that you posted, you are only using the second and third tokens
token1 is NetPathmed=
token2 is **IPaddress**
token3 is C
token 4 is \folder\file. I just need the IP address
Note that you specified / not \. Different animal. Chalk and cheese.
So - all you'd need to do is assemble the various elements %var1% %%c and %%d together with the fixed text you require, replace the echo with net use after testing and you should be off...
This Supybot for windows batch install script needs to create another batch file...
The Problem:
(1) I have a directory that has a file that ends with .conf
(2) There is only one file in this directory that ends with .conf
(3) But I don't know what this file starts with.. all I know is ????????.conf
(4) How do I set the filename.conf and remove the .conf part of the file name?
(5) As it is just the beginning of the filename that I need.
Example:
C:\runbot>find "supybot.ident: " | type *.conf > temp.txt
robotbot.conf
Outputs : robotbot.conf
The quest, is how do I set a variable=robotbot
=========================================================================
The Input was this file named "RootCode.conf" among many others
within the directory searched:
RootCode.conf
The Solution is:
FOR /F "tokens=1,2 delims=." %%a in ('FINDSTR /M "supybot.ident:" *.conf') DO SET USER=%%a&set dontneed=%%b
echo %USER%
pause
The Output is:
C:\runbot>FOR /F "tokens=1,2 delims=." %a in ('FINDSTR /M "supybot.ident:" *.con
f') DO SET USER=%a & set dontneed=%b
C:\runbot>SET USER=RootCode & set dontneed=conf
C:\runbot>echo RootCode
RootCode
C:\runbot>pause
Press any key to continue . . .
Winner... Special thanks Everyone
Your example of piping the output to typecommand is either wrong or useless. So I am assuming you mistyped and the real line was piping the other way around, and thus I am assuming that you are trying to find the filename of the file that contains the string "supybot.ident: ". In that case I would suggest to use findstr command instead.
FOR /F "tokens=*" %%a in ('FINDSTR /M "supybot.ident:" *.conf') DO SET USER=%%a
See HELP FINDSTR, HELP SET and HELP FOR for more information.
It's a bit unclear (to me, at least) what exactly you ask here. But if you need the output of a command, then use for /f:
for /f "delims=" %%x in ('some command ^| line') do set somevar=%%x
Note that you need to escape shell metacharacters in the command line (as they need to survive one parsing pass). Also note that you cannot set a variable to contain more than one line of text.