I'm reading strings from a file using a simple batch file:
echo off
for /f %%x in (%1) do (
echo %%x
)
What I actually want to do is extract the last character of the string, using a substring expression in the form "%x:~-1%"
I can't get this to work with the "%%x" variable in the for loop.
So I tried adding a "set" statement to the for loop:
echo off
for /f %%x in (%1) do (
echo %%x
set temp=%%x
echo %temp:~-1%
)
Problem is, it appears that "temp" is set only once, to the contents of the first string, and is never changed thereafter.
Is there a better way to approach this?
Thanks!
How to manipulate a "%%x"- type string read from a file?
Moderator: DosItHelp
Re: How to manipulate a "%%x"- type string read from a file?
@echo off
setlocal enabledelayedexpansion
for /f %%x in (%1) do (
echo %%x
set temp=%%x
echo !temp:~-1!
)
endlocal
setlocal enabledelayedexpansion
for /f %%x in (%1) do (
echo %%x
set temp=%%x
echo !temp:~-1!
)
endlocal
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: How to manipulate a "%%x"- type string read from a file?
The command interpreter expands %% variables within loops and brackets and such before processing and not during, which is why delayed expansion (using !!) was added to Command Prompt's features.
%x:~-1% does not work because %%x is not actually a variable, it's an argument. %% makes an escaped %, non-numerical arguments are expanded after the command character processing phase. That's why when you type %%x arguments straight into Command Prompt, it needs to be just %x. Forms like %1 and %%x have their own special functions like %~1, %~dp1, %~z1 etc though (check for /?).
So,
will only read the first string of characters up to the first space or tab (for /f's default space and tab delimiters).
Anyways, you do have to pass the data to a variable first. I believe this is what you want to do:
%x:~-1% does not work because %%x is not actually a variable, it's an argument. %% makes an escaped %, non-numerical arguments are expanded after the command character processing phase. That's why when you type %%x arguments straight into Command Prompt, it needs to be just %x. Forms like %1 and %%x have their own special functions like %~1, %~dp1, %~z1 etc though (check for /?).
So,
Code: Select all
for /f %%x in (%1) do ...
will only read the first string of characters up to the first space or tab (for /f's default space and tab delimiters).
Anyways, you do have to pass the data to a variable first. I believe this is what you want to do:
Code: Select all
@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%x in (%1) do (
set "myvar=%%x"
echo:!myvar:~-1!
)
Re: How to manipulate a "%%x"- type string read from a file?
Hi vltreude,
as Masiosare and orange_batch explained, the delayed expansion is a good way to solve your problem.
But there could be problems with carets "^" and exclamation marks "!"
If in your text are these characters, you will lose the exclamation marks and,
if at least one exclamation mark is found you also lose the carets.
This line cause the problem, because first the %x expands, and then the "!" and "^" are interpreted.
It's not possible to solve this with enabled delayed expansion
But you can use
This works, because the set "myvar=%%x" is safe, as the delayed expansion is disabled.
But then, you can not directly access the variable, therefore you can enable the delayed expansion.
Or you can try to use the call echo %%myVar%%, but then you have to keep the special characters in mind.
hope it helps
jeb
as Masiosare and orange_batch explained, the delayed expansion is a good way to solve your problem.
But there could be problems with carets "^" and exclamation marks "!"
If in your text are these characters, you will lose the exclamation marks and,
if at least one exclamation mark is found you also lose the carets.
Code: Select all
set "myVar=%%x"
This line cause the problem, because first the %x expands, and then the "!" and "^" are interpreted.
It's not possible to solve this with enabled delayed expansion
But you can use
Code: Select all
@echo off
setlocal DisableDelayedExpansion
for /f "delims=" %%x in (%1) do (
set "myvar=%%x"
setlocal EnableDelayedExpansion
echo(!myvar:~-1!
endlocal
)
This works, because the set "myvar=%%x" is safe, as the delayed expansion is disabled.
But then, you can not directly access the variable, therefore you can enable the delayed expansion.
Or you can try to use the call echo %%myVar%%, but then you have to keep the special characters in mind.
hope it helps
jeb
Last edited by jeb on 22 Nov 2010 17:19, edited 1 time in total.
Re: How to manipulate a "%%x"- type string read from a file?
Wow, it works!
I never before understood the difference between arguments and variables in a DOS script, and why the behavior of the BAT file was so different than that of a compiled program.
Thanks, guys!
I never before understood the difference between arguments and variables in a DOS script, and why the behavior of the BAT file was so different than that of a compiled program.
Thanks, guys!
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: How to manipulate a "%%x"- type string read from a file?
Heh, I know the problem jeb speaks of even as I typed my previous response. I neglect to explain it since I've yet to implement it myself in the program I've been working on (it does some crazy text processing)... so I hope it doesn't become catastrophic just to add support for exclamation marks, lol.
If I run into any particular issues, I'll probably start a thread on it if not just for other people's educational use.
If I run into any particular issues, I'll probably start a thread on it if not just for other people's educational use.
Re: How to manipulate a "%%x"- type string read from a file?
In this example it is easy with toggling the delayed expansion, because the content is only echo'd.
But if you want to keep the value(s), it's quite more tricky, because the endlocal destroys the variables again.
jeb
But if you want to keep the value(s), it's quite more tricky, because the endlocal destroys the variables again.
jeb