Batch: Problem reading text file contents into a variable - batch-file

:check
set /p default=<%USERPROFILE%\default_environment.txt
echo "The default is: " %default%
IF EXIST %USERPROFILE%\default_environment.txt (
echo "default exists"
echo "file contents: " & type %USERPROFILE%\default_environment.txt
#REM type %USERPROFILE%\default_environment.txt >
) ELSE (
echo "default does not exist"
)
IF %default%.==. (
echo "Launching the dialog"
%VIRTUAL_ENV%\python %USERPROFILE%\environmentGUI.PY
goto check
)
First time through the loop, the file is empty. Second time through the loop, the first line of the file is read and contents are set to the variable "default." This is expected behavior since I only need to read four characters in. Any ideas as to why this is happening? I know this isn't a whitespace issue, since the second time around, the first line of the file is being read just fine.

Related

Windows Batch file - Delete with Y/N prompt and not allow wild cards

I don't think this is a duplicate question (much to my surprise). I'm not a fan of using batch files and I can count on 1 hand the number of times I've had to create one.
I'm trying to create a batch file for deleting 1 file at a time, without wild cards. If the file name doesn't exist, then the batch file should terminate.
My errant batch file:
#echo off
set /p image="Enter file name (e.g. car.jpg):"
set fullFileName=C:\testimages\%image%
IF EXIST "%fullFileName%" (
ECHO[
del /P /F "%fullFileName%"
) ELSE (
ECHO File %fullFileName% doesn't exist
)
pause
Correct:
Enter file name (e.g. car.jpg):car.jpg
C:\testimages\car.jpg, Delete (Y/N)?
Correct:
Enter file name (e.g. car.jpg):plane.jpg
File C:\testimages\plane.jpg doesn't exist
Press any key to continue . . .
I want to disallow any wild cards. Such as the following:
Enter file name (e.g. car.jpg):*
C:\testimages\bus.jpg, Delete (Y/N)? n
C:\testimages\car.jpg, Delete (Y/N)? n
C:\testimages\truck.jpg, Delete (Y/N)? n
Press any key to continue . . .
I am assuming you want to disallow the user entering in * or ?. There are other undocumented wildcards as well though.
#echo on
:loop
cls
set /p "image=Enter file name (e.g. car.jpg):"
(echo "%image%"|findstr /L "* ? < > ^" >nul 2>&1) && GOTO :EOF
set "fullFileName=C:\testimages\%image%"
IF EXIST "%fullFileName%" (
ECHO[
ECHO del /P /F "%fullFileName%"
) ELSE (
ECHO File "%fullFileName%" doesn't exist
)
endlocal
pause
There are probably more robust ways to check for input validation. I am sure this could be broken in some form.
Here is an option using the for /F command:
set "image=" & set /P image="Enter file name: "
for /F tokens^=1*^ delims^=?*^<^>^" %%A in ("_%image%_") do set "TEST=%%B"
if defined TEST echo There are wild-cards!
If at least one wild-card is present in %image%, %%B and hence TEST are not empty. The _ characters are prepended and appended for the approach not to fail in case wild-cards are only present at the beginning and/or at the end of %image%.
This is another option using a standard for loop:
set "image=" & set /P image="Enter file name: " & set "FLAG=#"
for %%A in ("%image%") do if /I "%image%"=="%%~nxA" (set "FLAG=") else goto :QUIT
:QUIT
if defined FLAG echo There are wild-cards!
If at least one wild-card is present in %image%, the for loop resolves it by accessing the file system and returning the matching items (zero or more); this means that the original string %image% does not equal any of the iterated items, so the if query fails; the goto is there to avoid any more iterations, hence to break the loop; if no items match, the loop does not iterate at all. If no wild-cards are present in %image%, the for loop iterates once only over the original string, hence the if condition is fulfilled and variable FLAG is cleared.

set /p with spaces in variable value

I wanted to make a basic text editor in batch and I'm using set /p to get user input and write that to a file.
When I type in something like "hello" or "hello " it works fine, but as soon as I write something with a space and another character after than, like "hello world", the window closes.
My code was:
set /p append=Write what you want to append:
Then I tried:
set /p "append=Write what you want to append: "
which i found online, but it didn't work.
pause isn't of any help because the program crashes as soon as I press enter.
Help!
Here is the full code:
:append
set /p "append=Write what you want to append: "
if %append%==return (
cls
goto start
)
echo %append% >> %filename%
goto append
:override
cls
echo Name: %filename%
set /p override="Write new content: "
echo %override% > %filename%
pause
cls
goto start
:writefile
echo.
set /p filename=Write file name.extension:
choice /c AO /m "Append to file or override? "
if %ERRORLEVEL%==1 (
cls
echo Name: %filename%
goto append
) else (
goto override
)
Whenever the user of a batch file is prompted for a string using set /P the user has the freedom to
enter nothing at all by pressing simply just RETURN or ENTER which results in the environment variable is still not defined after prompt if it was not defined before, or the variable keeps its current value if it was already defined before, or
enter really anything including a string which could result in an exit of batch execution because of a syntax error somewhere in batch code later or an unwanted behavior.
Let us look on the line
if %append%==return (
If environment variable is not defined before with a default value and the batch user enters nothing, this line expands during preprocessing step to:
if ==return (
This command line is of course invalid and results in an exit of batch processing because of a syntax error.
Now let us assume the user enters the string:
I want to append this string.
Then the IF command line expands to:
if I want to append this string.==return (
And of course also this command line is invalid.
The other answerers suggested to enclose the two strings to compare in double quotes, i.e. use the command line:
if "%append%"=="return" (
But does that really solve all possible issues?
Is the code now really safe against any user input.
Let us look what happens if the user enters the string:
" is a double quote. It should be used around paths like "%ProgramFiles(x86)%".
The IF command line expands now to:
if "" is a double quote. It should be used around paths like "%ProgramFiles(x86)%""=="return" (
And this command line is again invalid and results in an exit of the batch file because of a syntax error.
So how to make batch code safe against really any user input?
The solution is using delayed environment variable expansion wherever the user entered string is referenced.
Example:
#echo off
setlocal EnableDelayedExpansion
echo.
echo Enter EXIT to exit this batch script.
:PromptUser
echo.
set "UserInput=Nothing^!"
set /P "UserInput=Please enter a string: "
if /I "!UserInput!" == "exit" goto EndBatch
echo You entered: !UserInput!
goto PromptUser
:EndBatch
echo.
echo Thanks for running this example batch code.
echo.
echo The batch file ends in 3 seconds ...
endlocal
%SystemRoot%\System32\ping.exe localhost -n 4 >nul
By using delayed expansion the user entered string can't result in a invalid or unexpected command line in later code. This is also important for the command line
echo !append!>>%filename%
It is important to have no space character left of >> or this space character is also written into the file as trailing space.
But delayed expansion is also important here in case of user enters for example just 2 which would result with echo %append%>>%filename% in
echo 2>>%filename%
which does not append the character 2 to the file, but would append STDERR to the file which results in an empty line written to the file.
Delayed expansion is also needed for this string entered by the user:
(Var1 > 0x2F) && (Var1 < 0x3A)
which should be written with ECHO into the file as entered and not what Windows command interpreter would produce after expanding the string when using echo %append%>>%filename%.
Change your set to put quotes in the right place around the prompt string, and your if line to put quotes around the string being tested.
set /p append="Write what you want: "
set append
echo xx%append%yy
if "%append%"=="return" (
echo Yes!
)
Your problem is with
if %append%==return (
which will give a syntax error if append contains spaces.
use
if "%append%"=="return" (
"quoting a string" makes cmd interpret it as a single element so the required syntax of if,
if string==string (
is no longer violated.

How to print multiple text files within a batch file

I have reached a little bit of a brick wall. I understand how to print a single text file within a batch file via Notepad but I am stuck when it comes to multiple text files. Here is what I have so far that really is not working correctly at all:
set /P PrinterFile= "Enter File Name:" | set PrinterFile2= "" | set PrinterFile3= "" | set PrinterFile4= "" | set PrinterFile5= ""
if %PrinterFile%== ""(
echo please enter valid file
pause
) else (
notepad.exe /P %PrinterFile%
)
pause
I did not finish the if statements to check for the others because I cannot get the first one to work. Can anyone point me in the correct direction? Thank you!
In the end it needs to be able to take from 0 to 5 text files. for example (name of batch file is printer.bat):
printer file1.txt file2.txt file3.txt
printfiles.bat
#echo off
setlocal
for %%f in (%*) do (
if exist "%%~f" (notepad.exe /P "%%~f"
) else (
if exist "%%~f.txt" (notepad.exe /P "%%~f.txt"
) else (
echo "%%~f" not found
)
)
)
[untested]
This should work. It simply processes the namelist provided as a parameter so
printfiles abc,def,ghi,yellow.txt
would print the files (abc or abc.txt) and (def or def.txt) and (ghi or ghi.txt) and (yellow.txt or yellow.txt.txt) if the files exist.
Does that solve your problem?
Full-blown version
#ECHO OFF
SETLOCAL
:: Get file list from command line
SET "filelist=%*"
IF DEFINED filelist GOTO printthem
CLS
ECHO Press ENTER to START printing
:nextfile
SET "filename="
SET /p "filename=Print : "
IF DEFINED filename SET "filelist=%filelist%,"%filename%""&goto nextfile
IF NOT DEFINED filelist ECHO no files specified&GOTO :EOF
:printthem
for %%f in (%filelist%) do (
if exist "%%~f" (notepad.exe /P "%%~f"
) else (
if exist "%%~f.txt" (notepad.exe /P "%%~f.txt"
) else (
echo "%%~f" not found
)
)
)
GOTO :EOF
First thing : load filelist from command-line, so executing printfiles abc,def,ghi,yellow.txt would assign abc,def,ghi,yellow.txt to filelist. If there are no supplied parameters, assign nothing to filelist.
If filelist is defined (ie, contains a value which implies command-line parameters were supplied) then go to the label printthem
Otherwise, clear the screen and how the message Press ENTER to START printing
Then set filename to nothing (because set /p with simply Enter will leave the value unchanged) and prompt for input with Print :. Keyboard input will be placed into filename.
if there was a (presumed, filename) entry made, then accumulate "the filename" to the end of filelist after a comma and repeat the request for a filename.
When simply Enter is used, filename will be empty, hence undefined so we proceed to :printthem provided filelist is not empty.
From there, we simply process filelist as a comma-separated series of
filenames into %%f. If the filename as-entered exists, use notepad to print it, if it doesn't, try appending .txt to the name and if even that fails, show an error message.
The %%~f removes the quotes from the item in %%f. This is then re-quoted so that filenames containing spaces may be printed.

Why is the string of a variable redirected to a file with trailing space and not correct displayed after read from file?

I'm trying to work with batch, but I'm having some bugs that I didn't have before making similar applications.
First issue:
I'm using set /p to prompt for a string, then I save it to a file using
ECHO Myvar>"%systemroot%\name.ini"
That works fine, but when I open the file name.ini there is a space after the string I typed. I built already a batch in the past using this and it didn't happen.
Second issue:
When I load the file to string, it doesn't work. Something happens to the string that if I try to output it using
ECHO %Myvar%
the output is ECHO is off. As I said before, I used this once already in a different batch file and it worked fine.
Example code:
#ECHO OFF
if not exist "%systemroot%\asd.ini" (
set /p asd= COMR:
ECHO %asd%>"%systemroot%\asd.ini"
REM Save the string to a file
) else (
set /p asd=<"%systemroot%\asd.ini"
REM Read the string
ECHO %asd%
pause
)
P.S: I already tried using SETLOCAL EnableDelayedExpansion, but it still doesn't work as expected.
setlocal enabledelayedexpansion
if not exist "%systemroot%\asd.ini" (
set /p asd= COMR:
ECHO !asd!>"%systemroot%\asd.ini"
REM Save the string to a file
) else (
set /p asd=<"%systemroot%\asd.ini"
REM Read the string
ECHO !asd!
)
pause
Stuff in brackets are treated as one line.
I removed Echo Off - hiding messages is not a good idea when you have a problem.

Batch, How To Read in a Blank Line of Text File

i need to read in the first line and identify whether it is blank or string of number. If it is blank line, the program will tell this text is invalid then terminate otherwise i will use that string to do further calculation.
BUT, The code i used is below, it just can not store the blank line such that i can not use if-statement to check whether it is null or "". Any suggestion?
set "text_file=20150629_eleave_i_test.txt"
:: Get the first six characters of the first line
set /p first_six=<%text_file%
If the text file in the view of notepad++ is
1
2 00000720150625
Thank you for advance.
This should work:
set "text_file=20150629_eleave_i_test.txt"
set "first_line="
set /p first_line=< %text_file%
if not defined first_line (
echo This text is invalid
goto :EOF
)
set "first_six=%first_line:~0,6%"
#echo off
setlocal enableDelayedExpansion
set "ln="
set /p "ln=" <"20150629_eleave_i_test.txt"
if not defined ln (
echo First line is empty
) else (
for /f "delims=0123456789" %%A in ("%ln%") do echo First line is not fully numeric
) || echo First line is fully numeric

Resources