0

Is there a way to run more than one command on the same line where the first command is a "for loop" in a windows bat file?

For example run these three commands on the same line:

for /f %%i in ('echo bar') do set result=%%i set foo=%result% echo %foo% // Displays: bar

Below example didn't originally work but works now after adding delayed expansion per the suggestion in the comments (for future reference):

setlocal enabledelayedexpansion (for /f %%i in ('echo bar') do set result=%%i) & set foo=%result% & echo %foo%

So by putting parenthesis around the for loop related commands and using delayedexpansion, more commands can be added with the ampersand separator.

Replacing the for loop with a simpler command also works with delayedexpansion:

setlocal enabledelayedexpansion set result=bar & set foo=%result% & echo %foo% // displays: bar

So per the comments all of the above now work, the last two examples by adding setlocal enabledelayedexpansion.

Thanks all.

PS: I don't see this is a duplicate question per aschipfl since my question was how to get the three commands to work on one line where one of the commands is more complex (a for loop with its own command(s)). There's no way to find that answer from the question indicated via a search unless one knows in advance to search for delayedexpansion, in which case the question wouldn't be neccessary since that's the answer. The answers may be the same, but the questions are different.

ciso
  • 2,887
  • 6
  • 33
  • 58
  • 2
    This is a classic [delayed expansion problem](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected/30284028#30284028) – Stephan Aug 02 '19 at 07:41
  • 3
    It's a [tag:batch-file], there's no need to put everything on the same line, but we're you to do so, delayed expansion, would be useful. – Compo Aug 02 '19 at 07:42
  • 1
    As an additional note, the command example which you gave us at the bottom of your question as **works**, does not work either. It would need to look more like this, `@Set "result=bar" & Call Set "foo=%%result%%" & Call Echo %%foo%% & Pause`, or this, `@Set "result=bar" & Call Set "foo=%%result%%" & Set foo & Pause`. In both examples the `& Pause` is included just to give you sufficient time to see the output, if necessary. – Compo Aug 02 '19 at 08:33
  • For your `for` loop version, the following may also be acceptable, `@(For %%A In (bar) Do @Set "result=%%A") & Call Set "foo=%%result%%" & Call Echo %%foo%% & Pause` or `@(For %%A In (bar) Do @Set "result=%%A") & Call Set "foo=%%result%%" & Set foo & Pause`. – Compo Aug 02 '19 at 08:40
  • 2
    Do `set "foo="` in advance, then execute your code fragments; you'll see that none but the very first are actually working due to lack of [delayed expansion](https://ss64.com/nt/delayedexpansion.html); not clearing `foo` just lets you display the value present *before* your code executed (like from a previous attempt, for instance)... – aschipfl Aug 02 '19 at 08:47
  • See edits I made taking comments into account. It works now. Thank you. – ciso Aug 03 '19 at 20:10
  • @compo the reason the example at the bottom worked for me is because I had delayedexpansion on at the time and didn't realize the impact of it. – ciso Aug 03 '19 at 20:16
  • Your question edit is unnecessary, as you're not seeing things in quite the same way as the commenters. Your question is really, "How do I `set` a string value to a variable and then use that variable within the same _single or multi_ line code block"? – Compo Aug 03 '19 at 20:18
  • @compo Well my question was and is as stated. I was focusing on separating a for loop from other simpler commands and putting all of this on the same line. I could change the question per your suggestion but that's more general than what I was searching for. I'll leave it as is since others may search for the same thing. For loops being more complex constructs than simple one line set statements and combining a for loop with these simpler commands on one line is not intuitive, or at least wasn't to me. – ciso Aug 03 '19 at 20:23
  • 1
    In reply of your PS: "marked as duplicate" doesn't mean, it's a bad question and doesn't imply you didn't your part of research (in that case it would have been downvoted and deleted). We are well aware that it's hard to search for something you don't know of. "Duplicate" only says "There is already an answer to this issue" (although the questions themselves may look very different). Duplicates help to keep this site clean and avoid answering the same issue again and again. – Stephan Aug 03 '19 at 20:25
  • By the way: a working batch would look like `setlocal enabledelayedexpansion` and `(for /f %%i in ('echo bar') do set result=%%i) & set foo=!result! & echo !foo!` – Stephan Aug 03 '19 at 20:28
  • 1
    You said `I'll leave it as is since others may search for the same thing.`. That's the exact purpose of duplicates: different search terms may lead to different questions that (ideally) all point to a single "best" answer. Otherwise, we would just delete "unneeded" questions. – Stephan Aug 03 '19 at 20:37
  • Ok. I thought duplicate meant it's a useless question since it was already asked and implies I didn't research properly and posted an unnecessary duplicate question which was already asked and answered: per ashifpl: "This question has been asked before and already has an answer..." Thanks for clearing that up. I won't look at it as a bad mark any more. – ciso Aug 03 '19 at 20:40

0 Answers0