0

I need to read the content of a text file word by word, in a batch script. The words are space separated. I tried this but it doesn't work, it only takes the first word:

for /f "delims= " %%i in (%OUTPUT_FILE%) do echo %%i

I also tried this but doesn't work also:

for /f "tokens=* delims= " %%i in (%OUTPUT_FILE%) do echo %%i
georgiana_e
  • 1,809
  • 10
  • 35
  • 54

3 Answers3

6
for /f "delims=" %%a in (file.txt) do for %%b in (%%a) do echo %%b

Delimiters: space, tab, 0xFF, , ; =.

Endoro
  • 37,015
  • 8
  • 50
  • 63
1

Here is a pure batch solution that should be able to handle any content in your file. It reads each line with an outer FOR /F, and replaces each space with a newline character. It reads each resulting line (word) with an inner FOR /F.

@echo off
setlocal disableDelayedExpansion

:: Define LF to contain a newline character
set LF=^


:: Above 2 blank lines are critical - DO NOT REMOVE

for /f "eol= tokens=*" %%A in (%OUTPUT_FILE%) do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  for %%L in ("!LF!") do for /f "eol= " %%W in ("!ln: =%%~L!") do echo(%%W
  endlocal
)

Life is much simpler if you use a hybrid JScript/batch utility called REPL.BAT that performs regex search and replace on stdin and writes the result to stdout.

Assuming REPL.BAT is in your current folder, or better yet, somewhere within your PATH:

for /f "eol= " %%W in ('repl " " "\n" x ^<%OUTPUT_FILE%') do echo(%%W
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Nice trick setting LF. I'm going to save that for future use. Should the enableDelayedExpansion really be included in the loop though? Could the local statements be placed around the first loop to reduce it getting called repeatedly? – Parrish Husband Oct 01 '13 at 22:15
  • 1
    @Locke - Delayed expansion will corrupt the expansion of `%%A` if the value contains `!`. That is why I toggle delayed expansion on and off within the loop, after the value is already assigned. – dbenham Oct 02 '13 at 05:47
  • It worked like that, but i still have a problem, windows has a 8k limitation for command length. My OUTPUT_FILE contains more than 8k and when i do that: "for /f "eol= tokens=*" %%A in (%OUTPUT_FILE%) " the content of OUTPUT_FILE is expanded then the batch script is stoped. Do you have any idea how can I overcome that. Thanks. – georgiana_e Oct 02 '13 at 06:45
  • @georgiana_e - I'm not aware of a pure batch solution for lines longer than 8k. But my 2nd solution (the one liner) that uses REPL.BAT should work with any line length. – dbenham Oct 02 '13 at 06:55
  • 1
    Does not work if the word is "on" as it believes it is echo on – JustAFellowCoder Sep 23 '21 at 14:39
  • 1
    @JustAFellowCoder - Yes, you are correct. I updated the script to use `echo(%%W` instead of `echo %%W`. All should be good now. Thanks. – dbenham Sep 24 '21 at 17:13
  • @dbenham I cannot find in the documentation; what does the parenthesis after echo do; "echo("? Does it work for any command with arguments. – JustAFellowCoder Sep 28 '21 at 14:43
  • And what does the for loop in ("!LF!") do? for %%L in ("^") – JustAFellowCoder Sep 28 '21 at 15:33
  • 1
    @JustAFellowCoder - Both are undocumented hacks. `echo(` is the only known way to safely print any message with `echo` - it only applies to the `echo` command. More info within a long thread at https://www.dostips.com/forum/viewtopic.php?f=3&t=774. The `for %%L` loop is a hack to get a newline character in a FOR variable so it can later be used in search and replace. The more interesting bit is the definition of the `LF` variable to contain the newline. More info at https://stackoverflow.com/a/6379861/1012053. – dbenham Sep 30 '21 at 12:49
  • @JustAFellowCoder - Batch is largely a dysfunctional, crippled scripting language unless you are willing to learn about and use countless undocumented hacks. With the hacks you can do some sophisticated programming, but it is not for the faint of heart. – dbenham Sep 30 '21 at 12:57
  • @dbenham Thank you. I will check out those explanations. – JustAFellowCoder Oct 06 '21 at 14:18
0

Tokens control the elements split from delimiters that are available. So depending on what your overall goal is, it might be worth pursuing tokens to retrieve the desired variables. If you know how many elements will be on each line of your text file, such as a config file or key value pairs on each line, you could leverage 'tokens=' to get what you need.

for /f "tokens=1,2 delims= " %%a in (%OUTPUT_FILE) do echo %%a %%b

If the items per line is unknown, Endoro's word loop inside the line loop is definitely the way to go.

Parrish Husband
  • 3,148
  • 18
  • 40
  • 1
    what is `%%b` ? You defined only one token. `%%b` isn't a valid variable name here. – Endoro Oct 01 '13 at 11:32
  • I wanted to show how to pick specific positions in the variable array, but you're right that I may need to change it to tokens =1,2 to make %%b valid. I'll have to run this in a console, I'm typing on my phone on the way to work. – Parrish Husband Oct 01 '13 at 11:40