I am starting to program in batch and I have this problem. If I enter the variable by argument, it does not change the accented characters or character ñ, but if I declare the variable directly in the program, it does.
#echo off
set variable=%1
set variable=%variable:á=a%
set variable=%variable:é=e%
set variable=%variable:i=a%
set variable=%variable:ñ=n%
echo %variable%
set var=Holáéñ
set var=%var:á=a%
set var=%var:é=e%
set var=%var:ñ=n%
echo %var%
C:\Users\bruno\OneDrive\Escritorio\powershell>prova holáéñi
holáéña
Holaen
How can i fix this?
Refer to Mofi's comment :
You have to write the non ASCII characters using the code page which
is displayed on running in a command prompt window with your user
account chcp like the OEM code page 850 and not using the code page
defined for Windows GUI applications as default for single byte per
character encoded text files like Windows-1252. Or the batch file
contains at top after #echo off a line like
%SystemRoot%\System32\chcp.com 1252 >nul
You can write your batch like that :
#echo off
setlocal enableExtensions enableDelayedExpansion
set "cp="
for /F "tokens=2 delims=:." %%a in ('chcp') do set "cp=%%~a"
if not defined cp set "cp=850"
>nul chcp 1256
set var=Holáéñ
set var=!var:á=a!
set var=!var:é=e!
set var=!var:ñ=n!
echo !var!
>nul chcp %cp%
endlocal
pause & exit
Related
In a complex batch file I want to read in files with paths, among other things, to read them into a variable one after the other separated by spaces.
This works with the following code so far quite well - but only if the path does not contain an exclamation mark.
Even using the setlocal command (enabledelayedexpansion / disabledelayedexpansion) I did not succeed in processing exclamation marks.
Does anyone here have a clever idea to the problem?
The following example batch creates a text file in the current directory and then reads it in a for /F loop.
At the end all three paths from the text file should be in the variable %Output%. But with the exclamation mark.
#echo off
setlocal enabledelayedexpansion
echo This is an example^^! > "textfile.txt"
echo This is a second example^^! >> "textfile.txt"
echo And this line have an ^^! exclamation mark in the middle >> "textfile.txt"
for /F "usebackq tokens=* delims=" %%a in (textfile.txt) do (
set "Record=%%a"
set "Output=!Output!!Record! - "
)
)
echo %Output%
echo !Output!
endlocal
The Output is like this:
This is an example - This is a second example - And this line have an exclamation mark in the middle
But should be like this:
This is an example! - This is a second example! - And this line have an ! exclamation mark in the middle
It is advisable not using delayed variable expansion on processing files and directories, lines in a text file, strings not defined by the batch file itself, or output captured from the execution of a program or a command line. If it is for some reasons necessary to make use of delayed variable expansion inside a FOR loop, there should be first assigned the file/directory name, the line, or the string to process to an environment variable while delayed expansion is disabled and then enable delayed expansion temporary inside the FOR loop.
Here is a batch file demo which can be simply run from within a command prompt window or by double clicking on the batch file. It creates several files for demonstration in the directory for temporary files, but deletes them all before exiting.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example!> "%TEMP%\TextFile.tmp"
echo This is a second example!>> "%TEMP%\TextFile.tmp"
echo And this line has an exclamation mark ! in the middle.>> "%TEMP%\TextFile.tmp"
set "Output="
(for /F usebackq^ delims^=^ eol^= %%I in ("%TEMP%\TextFile.tmp") do set "Line=%%I" & call :ConcatenateLines) & goto ContinueDemo
:ConcatenateLines
set "Output=%Output% - %Line%" & goto :EOF
:ContinueDemo
cls
echo/
echo All lines concatenated are:
echo/
echo %Output:~3%
set "Output="
del "%TEMP%\TextFile.tmp"
echo File with name ".Linux hidden file!">"%TEMP%\.Linux hidden file!"
echo File with name "A simple test!">"%TEMP%\A simple test!"
echo File with name " 100%% Development & 'Test' (!).tmp">"%TEMP%\ 100%% Development & 'Test(!)'.tmp"
echo/
echo Files with ! are:
echo/
for /F "eol=| tokens=* delims=" %%I in ('dir "%TEMP%\*!*" /A-D /B /ON 2^>nul') do (
set "NameFile=%%I"
set "FileName=%%~nI"
set "FileExtension=%%~xI"
set "FullName=%TEMP%\%%I"
setlocal EnableDelayedExpansion
if defined FileName (
if defined FileExtension (
echo File with ext. !FileExtension:~1!: !NameFile!
) else (
echo Extensionless file: !NameFile!
)
) else echo Extensionless file: !NameFile!
del "!FullName!"
endlocal
)
endlocal
echo/
#setlocal EnableExtensions EnableDelayedExpansion & for /F "tokens=1,2" %%G in ("!CMDCMDLINE!") do #endlocal & if /I "%%~nG" == "cmd" if /I "%%~H" == "/c" set /P "=Press any key to exit the demo . . . "<nul & pause >nul
The output of this batch file is:
All lines concatenated are:
This is an example! - This is a second example! - And this line has an exclamation mark ! in the middle.
Files with ! are:
File with ext. tmp: 100% Development & 'Test(!)'.tmp
Extensionless file: .Linux hidden file!
Extensionless file: A simple test!
The text file example with concatenating lines makes use of a subroutine called from within the FOR loop processing the lines in the text file. The syntax used here is for maximum performance by getting the subroutine as near as possible to the FOR command line. That is important if the FOR loop has to process hundreds or even thousands of items.
The example processing file names enables and disables delayed expansion inside the FOR loop after having assigned all parts of the currently processed file to environment variables. It could be useful to reduce the list of environment variables before processing thousands of files for a better performance on using this method.
Another method is shown in Magoo´s answer using the command CALL to get a command line with referenced environment variables (re)defined inside the loop parsed a second time. I used that method also in the past quite often, but don't that anymore as it is not fail-safe and not efficient. call set results in searching by cmd.exe in current directory and next in all directories of environment variable PATH for a file with name set and a file extension of environment variable PATHEXT. So it results in lots of file system accesses in the background on each iteration of the FOR loop and if there is by chance a file set.exe, set.bat, set.cmd, etc. found by cmd.exe somewhere, the batch file does not work anymore as expected because of running the executable or calling the batch file instead of the (re)definition of the environment variable.
The following answers written by me could be also helpful:
How to read and print contents of text file line by line?
It explains in full details how to process all lines of a text file.
How to pass environment variables as parameters by reference to another batch file?
It explains in full details what the commands SETLOCAL and ENDLOCAL do.
How to pass a command that may contain special characters (such as % or !) inside a variable to a for /f loop?
This is an example of a batch file designed to process video files with any valid file name on any Windows computer very efficient, safe and secure with full explanation.
Well, the main trick is to enable delayed expansion only when it is actually needed and to disable it otherwise. Since you are accumulating multiple strings in a single variable inside of a loop, it becomes a bit more difficult, because you should have delayed expansion disabled during expansion of for meta-variables (like %%a), but enabled when joining the string, leading to setlocal and endlocal statements inside of the loop. The major purpose of these commands is environment localisation, hence any variable changes become lost past endlocal, so a method of tansfering the value beyond endlocal is required, which is incorporated in the following code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem /* At this point delayed expansion is disabled, so there is no need to
rem escape exclamation marks; moreover a redirected block prevents
rem superfluous file close/reopen operations, and there is no more
rem trailing space written to the file (as in your original approach): */
> "textfile.txt" (
echo This is an example!
echo This is a second example!
echo And this line have an ! exclamation mark in the middle
)
rem // Let us initialise the output variable:
set "Output= - "
rem // Using `usebackq` only makes sense when you want to quote a file path:
for /F "usebackq tokens=* delims=" %%a in ("textfile.txt") do (
rem // Remember that delayed expansion is still disabled at this point:
set "Record=%%a"
rem // For concatenation we need delayed expansion to be enabled:
setlocal EnableDelayedExpansion
set "Output=!Output!!Record! - "
rem /* We need to terminate the environment localisation of `setlocal`
rem inside of the loop, but we would lose any changes in `Output`;
rem therefore let us (mis-)use `for /F`, which is iterated once: */
for /F "delims=" %%b in ("!Output!") do endlocal & set "Output=%%b"
rem /* An often used method to transfer a variable beyond `endlocal` is
rem the line `endlocal & set "Output=%Output%`, but this only works
rem outside of a parenthesised block because of percent expansion. */
)
rem /* Echo out text with delayed expansion enabled is the only safe way;
rem surrounding separators ` - ` are going to be removed; since `Output`
rem was initialised with something non-empty, we do not even need to skip
rem sub-string expansion for the problematic case of an empty string: */
setlocal EnableDelayedExpansion
echo(!Output:~3,-3!
endlocal
endlocal
exit /B
Pew. I finally got it to work.
It works via a workaround using a second text file.
Not pretty, not performant, but it works and is sufficient for my purposes.
#Magoo, thanks for your post.
This is my solution:
#echo off
setlocal enableextensions enabledelayedexpansion
echo This is an example^^!> "textfile.txt"
echo This is a second example^^!>> "textfile.txt"
echo And this line have an ^^! exclamation mark in the middle>> "textfile.txt"
echo.
echo Content of the textfile:
type "textfile.txt"
set output=
del "textfile2.txt" 1> nul 2>&1
setlocal disabledelayedexpansion
for /f "usebackq tokens=* delims=" %%a IN ("textfile.txt") do (
rem Write each line without a newline character into a new text file
echo|set /p "dummy=%%a, ">>"textfile2.txt"
)
endlocal
rem Loading the content of the new text file into the variable
set /p output=<"textfile2.txt"
del "textfile2.txt" 1> nul 2>&1
echo.
echo --------------------------------------------
echo Content of the variable:
set out
endlocal
The output looks like this:
Content of the textfile:
This is an example!
This is a second example!
And this line have an ! exclamation mark in the middle
--------------------------------------------
Content of the variable:
output=This is an example!, This is a second example!, And this line have an ! exclamation mark in the middle,
It's delayedexpansion mode that appears to raise this problem.
#ECHO OFF
setlocal enabledelayedexpansion
echo This is an example^^^! > "textfile.txt"
echo This is a second example^^^! >> "textfile.txt"
echo And this line have an ^^^! exclamation mark in the middle >> "textfile.txt"
TYPE "textfile.txt"
SETLOCAL disabledelayedexpansion
for /F "usebackq tokens=* delims=" %%a in (textfile.txt) do (
set "Record=%%a"
CALL set "Output2=%%Output2%%%%record%% - "
CALL set "Output=%%Output%%%%a - "
SET out
)
)
endlocal&SET "output=%output%"
echo %Output%
echo !Output!
SET out
I've no doubt that with delayedexpansion off, there would be the same problem with %. Just special characters, I suppose.
Note that with endlocal&SET "output=%output%", the set is executed in delayedexpansion mode.
so I'm just wondering if it's possible to to make a batch file read a line of text but split every letter up into it's own variable, ex:
#echo off
:start
set /p text=input:
set out=
set out2=
set /p text=input:
:loop
set out=%out% %text:~0,1%
set out2=%out2:~1% %text:~1%
set text=%text:~1%
if defined text goto loop
echo %out% -%out2%
pause
goto start
What I've written here doesn't work (I was just fiddling around trying to find the answer)
But what I was trying to do was to make "out" and "out2" into 2 separate values. Where "out" would be the first letter typed, and "out2" would be the second letter and so on. (planning to have about 16 out's that can read the first 16 letters of whatever the user inputs and make it into separate varibles)
ex: typing "ab" in the same line would result in "out" being "a" and "out2" being b
Another thing I couldn't figure out either was how to stop "out" from reading everything after the first letter. If anyone could help me with this issue, please explain what you've done to fix it. Thanks in advance
Here is a little trick you can use with CMD.exe and the /U option. The FOR /F command is necessary to capture the output to assign to a variable. I then build a pseudo array with the cnt variable. The SET out command is just used to display all the variables in the pseudo array.
#echo off
setlocal
SET /P "text=INPUT:"
set "cnt=0"
for /F "delims=" %%G IN ('cmd /u /c "echo %text%"^|find /V ""') do (
set /A cnt+=1
CALL SET "out%%cnt%%=%%G"
)
FOR /L %%G IN (1,1,%cnt%) DO CALL echo %%out%%G%%
endlocal
pause
And here is just a quick run of the code.
C:\Users\Squashman\Desktop>so.bat
INPUT:foobar
out1=f
out2=o
out3=o
out4=b
out5=a
out6=r
Press any key to continue . . .
Here is the answer you provided but I fixed your logic errors.
#echo off
setlocal ENABLEDELAYEDEXPANSION
title Test
color a
mode 150
:start
cls
echo test
echo.
set /p text=Input:
set "texttmp=%text%"
set cnt=0
:Reader1
set /a cnt+=1
echo Val-%cnt% = !texttmp:~0,1!
set c[%cnt%]=!texttmp:~0,1!
set "texttmp=%texttmp:~1%"
if "%texttmp%" NEQ "" goto Reader1
I found an easy solution which is way easier to understand (for me at least)
#echo off
setlocal ENABLEDELAYEDEXPANSION
title Test
color a
mode 150
:start
cls
echo test
echo.
set /p text=Input:
set pos=1
:Reader1
echo Val-%pos% = !text:~%pos%,1!
set c[%pos%]=!text:~%pos%,1!
set /a pos=%pos%+1
if "!text:~%pos%,1!" NEQ "" goto Reader1
pause
The following creates a numbered list of links from a remote directory like
1 Link!1
2 Link!2
3 Link!3
4 Link!4
5 Link!5
.
#echo off
setlocal ENABLEDELAYEDEXPANSION
megals --reload /Root/
set /p var1="enter folder name: " & megals /Root/var1
set /a c=0
FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
set /a c=c+1
echo !c! %%i
set string[!c!]=%%i
)
set /P number=Enter number:
echo !string[%number%]!
pause
First Problem: All the links contain a ! character which gets removed by delayedexpansion, rendering the link useless. The links require the ! as it is part of the link.
Second Problem: I'm trying to integrate this into a program, and I can't use findstr because it will list the link and filename on the same line, and when the filenames contain parentheses the program crashes. So I have to use usebackq because it lets me get just the link, without needing to deal with the filenames.
Findstr will list Link!1 Filename (the whole line)
Usebackq lets me just get Link!1
I can't use Findstr because when filenames contain parentheses the program will crash, which can only be solved by delayedexpansion.
This is a follow-up post from here, which I got stuck on: (Shows the Program)
https://stackoverflow.com/questions/49564553/create-a-numbered-list-based-on-a-given-list-of-strings#=
You can see the findstr method there, and how it causes crashes when filenames contain parentheses, which can be fixed with delayedexpansion, but that removes the ! character which is essential as it is part of the link.
Edit: Seems to be working now, thanks
Working Code
#echo off
:start:
megals --reload /Root/
set /p var1="dir? " & megals /Root/%%var1%%
for /f "tokens=1,* delims=:" %%A in ('megals -n /Root/%%var1%% ^|findstr
/n "." ') do (
set Link[%%A]=%%B
Echo %%A %%B
)
setlocal DisABLEDELAYEDEXPANSION
set /a c=0
FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
set /a c+=1
call set "string[%%c%%]=%%i"
)
set /P number="Enter number: "
FOR /F "tokens=*" %%g IN ('call echo %%string[%number%]%%') do (SET VAR2=%%g)
echo %Var2%
echo.
Megadl %VAR2% & echo. && goto :start:
pause
https://megatools.megous.com/man/megals.html#_megatools
You really should double quote your whole set commands.
Using the alternate delayed expansion type with a call:
#echo off
setlocal DisABLEDELAYEDEXPANSION
megals --reload /Root/
set /p var1="enter folder name: " & megals /Root/var1
set /a c=0
FOR /F "tokens=1 usebackq" %%i in (`megals -n -e /Root/%%var1%%`) do (
set /a c+=1
call echo %%c%% %%i
call set "string[%%c%%]=%%i"
)
set /P number=Enter number:
call echo %%string[%number%]%%
pause
The simple solution is not using delayed environment variable expansion, for example by using command CALL.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
megals.exe --reload /Root/
rem Prompt user for folder name and verify that the user has really entered
rem a folder name and remove double quotes to prevent an exit of batch file
rem execution on further processing because of an invalid command line syntax.
:EnterFolder
set "FolderName="
set /P "FolderName=Enter folder name: "
rem Has the user entered anything at all?
if not defined FolderName goto EnterFolder
rem Remove all double quotes from folder name string?
set "FolderName=%FolderName:"=%"
rem Is anything left from folder name after removing double quotes?
if not defined FolderName goto EnterFolder
megals.exe "/Root/%FolderName%"
rem Get first space/tab separated string of each line output by megals
rem assigned to an environment variable which form an array of strings.
rem Redefine end of line character from semicolon to vertical bar as it
rem is impossible that a line starts with a vertical bar. Command CALL
rem is used to double process the SET command line by Windows command
rem processor which is the alternate solution for delayed expansion.
echo/
set "Count=0"
for /F "eol=|" %%I in ('megals.exe -n -e "/Root/%FolderName%"') do (
set /A Count+=1
call echo %%Count%% %%~I
call set "string[%%Count%%]=%%~I"
)
if %Count% == 0 echo There is nothing! & goto EndBatch
echo/
rem Prompt user for number name and verify that the user has really entered
rem a decimal interpreted number which must be in range of 1-%Count%.
:EnterNumber
set "Number="
set /P "Number=Enter number (1-%Count%): "
rem Has the user entered anything at all?
if not defined Number goto EnterNumber
rem Remove all double quotes from number string?
set "Number=%Number:"=%"
rem Is anything left from number string?
if not defined Number goto EnterNumber
rem Contains the number string any non digit character?
for /F "delims=0123456789" %%I in ("%Number%") do goto EnterNumber
rem Remove all leading zeros from number string to avoid interpreting
rem the entered number as octal number on the two IF comparisons below.
:LeadingZeros
if not %Number:~0,1% == 0 goto CheckNumber
set "Number=%Number:~1%"
if defined Number goto LeadingZeros
rem The number was 0 which is less than 1.
goto EnterNumber
rem Check number in range of 1 to %Count% which requires to convert the
rem number strings on both sides of the comparison operators to signed
rem 32-bit integers by Windows command processor in background.
:CheckNumber
if %Number% GTR %Count% goto EnterNumber
if %Number% LSS 1 goto EnterNumber
rem Output the string according to entered number by forcing Windows command
rem processor again to double processing the command line because of CALL.
call echo %%string[%number%]%%
rem Restore previous environment with discarding all the
rem environment variables defined by this batch file.
:EndBatch
endlocal
pause
Another solution is using a subroutine like OutputAndSet.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
megals.exe --reload /Root/
rem Prompt user for folder name and verify that the user has really entered
rem a folder name and remove double quotes to prevent an exit of batch file
rem execution on further processing because of an invalid command line syntax.
:EnterFolder
set "FolderName="
set /P "FolderName=Enter folder name: "
rem Has the user entered anything at all?
if not defined FolderName goto EnterFolder
rem Remove all double quotes from folder name string?
set "FolderName=%FolderName:"=%"
rem Is anything left from folder name after removing double quotes?
if not defined FolderName goto EnterFolder
megals.exe "/Root/%FolderName%"
rem Get first space/tab separated string of each line output by megals
rem assigned to an environment variable which form an array of strings.
rem Redefine end of line character from semicolon to vertical bar as it
rem is impossible that a line starts with a vertical bar. Command CALL
rem is used to double process the SET command line by Windows command
rem processor which is the alternate solution for delayed expansion.
echo/
set "Count=0"
for /F "eol=|" %%I in ('megals.exe -n -e "/Root/%FolderName%"') do call :OutputAndSet "%%~I"
if %Count% == 0 echo There is nothing! & goto EndBatch
echo/
rem Prompt user for number name and verify that the user has really entered
rem a decimal interpreted number which must be in range of 1-%Count%.
:EnterNumber
set "Number="
set /P "Number=Enter number (1-%Count%): "
rem Has the user entered anything at all?
if not defined Number goto EnterNumber
rem Remove all double quotes from number string?
set "Number=%Number:"=%"
rem Is anything left from number string?
if not defined Number goto EnterNumber
rem Contains the number string any non digit character?
for /F "delims=0123456789" %%I in ("%Number%") do goto EnterNumber
rem Remove all leading zeros from number string to avoid interpreting
rem the entered number as octal number on the two IF comparisons below.
:LeadingZeros
if not %Number:~0,1% == 0 goto CheckNumber
set "Number=%Number:~1%"
if defined Number goto LeadingZeros
rem The number was 0 which is less than 1.
goto EnterNumber
:OutputAndSet
set /A Count+=1
echo %Count% %~1
set "string[%Count%]=%~1"
goto :EOF
rem Check number in range of 1 to %Count% which requires to convert the
rem number strings on both sides of the comparison operators to signed
rem 32-bit integers by Windows command processor in background.
:CheckNumber
if %Number% GTR %Count% goto EnterNumber
if %Number% LSS 1 goto EnterNumber
rem Output the string according to entered number by forcing Windows command
rem processor again to double processing the command line because of CALL.
call echo %%string[%number%]%%
rem Restore previous environment with discarding all the
rem environment variables defined by this batch file.
:EndBatch
endlocal
pause
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.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
rem /?
set /?
setlocal /?
See also:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files
How to set environment variables with spaces?
Where does GOTO :EOF return to?
I'm using a for loop to acces a text file with a bunch of files + their directory formatted like this:
//srv/something/somethingelse/movie.mpg
//srv/something/somethingelse/movie2.mkv
//srv/something/somethingelse/movie3.mpg
//srv/something/somethingelse/movie4.mkv
I have to replace .mpg and .mkv with .xml, and then write that output away to another text file, which I'm trying to do like this:
for /F "tokens=*" %%A in (%~dp0temporary\movies.txt) do (
set string=%%A
set find=.mkv
set replace=.xml
set string=%%string:!find!=!replace!%%
set find=.mpg
set string=%%string:!find!=!replace!%%
echo %string%>>%~dp0temporary\xml.txt
)
The output I want is this:
//srv/something/somethingelse/movie.xml
//srv/something/somethingelse/movie2.xml
//srv/something/somethingelse/movie3.xml
//srv/something/somethingelse/movie4.xml
But what I get is this:
Echo is off.
Echo is off.
Echo is off.
Echo is off.
I have been searching on this for over an hour but I can't find anything that works
Here is the rewritten batch code which produces the expected output from input file.
#echo off
setlocal EnableDelayedExpansion
set "vidLoc=//srv"
set "resultLoc=c:"
del "%~dp0temporary\xml.txt" 2>nul
for /F "usebackq delims=" %%A in ("%~dp0temporary\movies.txt") do (
set "FileNameWithPath=%%A"
set "FileNameWithPath=!FileNameWithPath:.mkv=.xml!"
set "FileNameWithPath=!FileNameWithPath:.mpg=.xml!"
set "FileNameWithPath=!FileNameWithPath:%vidLoc%=%resultLoc%!"
echo !FileNameWithPath!>>"%~dp0temporary\xml.txt"
)
endlocal
All environment variable references enclosed in percent signs are expanded already on parsing entire for block. Just the environment variable references enclosed in exclamation marks are expanded delayed on executing the command. This can be seen on opening a command prompt window and running from there the batch file without #echo off at top or with this line being changed to #echo on.
Executing in a command prompt window set /? results in getting help of this command output on several window pages where usage of delayed expansion for for and if blocks is explained on a simple example.
And running in a command prompt window for /? prints help of command for into the output window.
For just replacing the file extension you could also use:
#echo off
del "%~dp0temporary\xml.txt" 2>nul
for /F "usebackq delims=*" %%A in ("%~dp0temporary\movies.txt") do (
echo %%~dpnA.xml>>"%~dp0temporary\xml.txt"
)
But this faster code changes also all forward slashes / to backslashes \ as the backslash character is the directory separator on Windows.
Mofi is right: move the line with setlocal enabledelayedexpansion out of any code block enclosed in (parentheses).
However, try next approach using Command Line arguments (Parameters) modifier ~:
#ECHO OFF >NUL
#SETLOCAL enableextensions
for /F "tokens=*" %%A in (%~dp0temporary\movies.txt) do (
rem full_path=%%~dpnA
rem extension=%%~xA
echo %%~dpnA.xml
)>%~dp0temporary\xml.txt
I had a look at the previous questions of your db and I didn't try an answer, but I try.
I would like to write the following lines code:
echo Executing backup....
backup procedure
echo Ok
but the output should be:
Executing backup... Ok
That's possible?!
I suppose you are using dos/nt-batch.
It is possible with the set /p command, because set /p doesn't print a CrLf
set /p "=Executing backup...." <nul
echo OK
Also it's possible to erase the line with a CR character.
It's important to know that whitespace characters at the front of an set /p are ignored (in Vista, not in XP), so the !cr! has to placed later or at the end.
A CR can only be displayed with delayedExpansion, because %cr% works, but CR characters are removed in the percent expansion phase(or directly after this phase), but not in the delayed expansion phase.
Example of a counter which use only one line for displaying
#echo off
setlocal EnableDelayedExpansion EnableExtensions
call :CreateCR
for /l %%n in (1,1,10000) do (
set /P "=Count %%n!CR!" <nul
)
echo(
goto :eof
:CreateCR
rem setlocal EnableDelayedExpansion EnableExtensions
set "X=."
for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094!
echo !X! > %temp%\cr.tmp
echo\>> %temp%\cr.tmp
for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do (
endlocal
set cr=%%a
goto :eof
)
goto :eof
EDIT: Explanation, how the variable cr is created (Done with a trick)
After setting variable X to a single dot (the character itself is unimportant), it is repeated to become 8188 characters by way of for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094!
Then the variable, two spaces and both a CR and LF are echoed into a file with echo !X! > %temp%\cr.tmp (Notice the two spaces between the !X! and the > and the natural line endings echo amends internally)
We now have 8192 characters, but the data buffer can only hold 8191 characters, so the last character (the linefeed) will be dropped!
In the next line echo\>> %temp%\cr.tmp, another CR/LF set is appended to the file (the \ in the command is just to output nothing bar the carriage return and line feed, as echo by it's self will output ECHO is ON/OFF), that's important, as a single CR can't be read at the end of a line (More later).
So the file now contains <8188 .'s><SPACE><SPACE><CR><CR><LF>
The for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do reads the second token, the delimters are standard space and tab, so the second token is only a single CR, as the following CR/LF is removed as standard line ending.
Finally the endlocal is used to return to an environment without the temporary variables X, c and a existing (As with the endlocal in brackets, it allows the setting of cr before the endlocal actually takes affect at the end of the brackets (could also be written as for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do endlocal&set cr=%%a&goto :eof)
Additionally
This was my first way to create a CR character, but it needs some time and a temporary file.
Later I saw a simpler method of retrieving the CR from a copy /z command.
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
Try this on Posix system (Linux)
echo -n "Executing backup.... "
echo -n "backup procedure "
echo "Ok"
It is much harder on Windows. You will need to use something like this:
#echo off
echo|set /p ="Executing backup...."
echo|set /p =" backup procedure"
Check this post: http://www.pcreview.co.uk/forums/showpost.php?s=1a20b16775d915998b30bd76a0ec5d35&p=4432915&postcount=7.
It's a bit of a hack, but here is an article describing how to do it for Windows.
From the article, the final result (edited for your setup) looks like this:
SET /P var=Backing up
%Result%....<NUL
Backup_process %Result% >NUL 2>&1
IF ERRORLEVEL 1
ECHO FAIL
ELSE
ECHO OK
I've done something similar using a VBScript.
Put this code in EchoNoNewline.vbs:
If WScript.Arguments.Named.Exists("TEXT") Then
WScript.StdOut.Write WScript.Arguments.Named.Item("TEXT")
End If
From your batch file, use the script like this:
CSCRIPT EchoNoNewLine.vbs //NOLOGO /TEXT:"Executing backup...."
backup procedure
CSCRIPT EchoNoNewLine.vbs //NOLOGO /TEXT:"Ok"
at What does a forward slash before a pipe in cmd do to remove the line ending of an echo?
the best suggestion is:
to echo text without a linefeed is very inefficient, as a pipe creates two new instances of cmd.exe.
It's much simpler and faster to use
<nul set /p "=My Text"
The redirect from NUL will also stop the waiting for user input.