首页 > 解决方案 > How to output multiple lines from a FINDSTR to a variable

问题描述

It's no surprise that the official documentation doesn't really help in the matter of understanding how does the command process the result of a command instead of a filelist neither why is it even called 'FOR'. Yes I already know stackoverflow is full of similar question but appearently, since batch scripts are influenced by so many "breaking" factors that, even as a non-batch experienced programmer, it is difficult not to get lost in the thousands exceptions and do-nots wich may affect the result. My objective, aside from learning from the best answer possible, is to formulate a generic enough question to represent the matter wich is probably the most common task including the FINDSTR command:

THE QUESTION:

How do I get the output of a FINDSTR in a way that allows me to compute every result line one at the time possibly INSIDE the loop?

The most 'generic' (batch bs-proof if you know what I mean) example I can make is the following:

Let's say this is secret_file.txt

some not intersting line
            A very intersting line = "secret1";
some not intersting line
            A very intersting line = "secret2";
some not intersting line
            A very intersting line = "secret3";
some not intersting line

Now with the findstr command i can output every "secret" line like this:

findstr /R /C:"secret.\"" secret_file.txt
                                A very intersting line = "secret1";
                                A very intersting line = "secret2";
                                A very intersting line = "secret3";

But this result is just useless without futher parsing right? I could have used ctrl-F over any text reader/editor for this matter, anyway, let's say I now want to output every line ONE AT THE TIME so that I can compute it, for example, saving every secret to a variable then using that variable somehow (it doesn't really matter how, we can just echo it to keep things simple).

Now, everybody agrees on the fact that for this kind of task, a FOR loop is needed. Quoting https://ss64.com/nt/for.html on the syntax, my script.bat should looks like this:

@echo off

FOR /F %%A IN ('findstr /R /C:"secret.\"" secret_file.txt') DO ECHO Batch script language is completely fine, good job Microsoft!

This just doesn't even give any output, can someone explain me why? My hypothesis was that the output from the findstr command is in a non-compatible format with the FOR command, not like I could check or something since the source is closed and the documentation doesn't even bother defining the word String. I'm ready to provide any details and even edit the question to be more visible to the wanna be microsoft-forsaken batch scripters out there.

标签: batch-filefor-loopcmdfindstr

解决方案


Using "tokens=*" to strip off leading spaces this batch uses a counter to create a (pseudo) array secret[]

:: Q:\Test\2018\12\04\SO_53614102.cmd
@Echo off
set Cnt=0
FOR /F "tokens=*" %%A IN (
  'findstr /R /C:"secret.\"" secret_file.txt'
) DO (
  set /a Cnt+=1
  call Set Secret[%%Cnt%%]=%%A
)
Set Secret[

Sample output:

> SO_53614102.cmd
Secret[1]=A very intersting line = "secret1";
Secret[2]=A very intersting line = "secret2";
Secret[3]=A very intersting line = "secret3";

As variables in a (code block) are expanded at parse time,
delayed expansion is requiered (here through a call and doubled %%)


推荐阅读