Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 911
  • Last Modified:

pipe output of one command to set /P

I want the first line of a DIR output in an environment variable. I tried

dir *.bat /T:C /O:-D /B | set /P test= 

Open in new window


That didn't set the variable. I got it running using the following command:

FOR /F "tokens=*" %I IN ('dir *.bat /T:C /O:D /B') DO SET test=%I) >NUL

Open in new window


Since FOR will loop through the whole directory listing, I don't really like it and would prefer to use the piping instead. Going through an external file is not an option.
0
cmnt
Asked:
cmnt
  • 3
  • 2
  • 2
  • +2
2 Solutions
 
wdosanjosCommented:
You can try this. It basically inverts the sorting so the first line becomes the last for the FOR to work.

FOR /F "tokens=*" %I IN ('dir *.bat /T:C /O:-D /B') DO @SET test=%I

Open in new window

0
 
cmntAuthor Commented:
With the piping I intended to catch the first line of the DIR output. After running FOR the test variable will contain the last line. Therefore piping and FOR need to have opposite sorting order. The FOR works as expected. The piping does not work at all. I am looking for a solution using piping, so I don't need to go through all entries in the folder. The folder may contain several hundred entries and I am only concerned about the newest one.
0
 
cmntAuthor Commented:
BTW, I missed one character in the second code line in my question. The correct line needs to be

(FOR /F "tokens=*" %I IN ('dir *.bat /T:C /O:D /B') DO SET test=%I) >NUL

Open in new window


Of course, I can leave out the outer parenthesis with the >NUL and just use @SET instead of SET as wdosanjos suggested. The sort order must be as stated in my question.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
sjklein42Commented:
test.bat

Exits loop after first file found (and set)

usage:

call test.bat >nul:

Open in new window


@FOR /F "tokens=*" %%I IN ('dir *.bat /T:C /O:D /B') DO (
@set test=%%I
@goto :EOF
)

Open in new window

0
 
QlemoC++ DeveloperCommented:
To answer the original question: Piping into set /P never works. You can only redirect a file. The reason for that is unknown, but it has been tried what has to be one google times, I suppose, to no avail.

There is indeed no other way than to use a file, or process the command stream with FOR.
Just to add another one (which isn't better or worse - this is the non-batch version):
>nul (set test=& for /F "delims=" %F in ('dir *.bat /t:c /o:-d /b') do if not defined test set test=%F)

Open in new window


sjklein42,
You need to use the reversed sort for that, as used in the very first code line shown by the asker.
0
 
wdosanjosCommented:
@cmnt,

> I am looking for a solution using piping, so I don't need to go through all entries in the folder.
> The folder may contain several hundred entries and I am only concerned about the newest one.

I think there is no way to avoid the IO required to iterate through all the entries in the folder.  First, dir has to find all entries that end with .bat, and then it needs retrieve the create dates for the sort.  By the time dir starts displaying the results all the IO on the folder is already done.
0
 
QlemoC++ DeveloperCommented:
wdosanjos is correct about that. Unlike in UNIX or Linux, a process writing into a pipe is always executed completely before passing the output to the pipe consumer. The dir is performed completely.
0
 
Bill PrewCommented:
Not much different than what has already been discussed, but here's how I typically handle this in a batch file:

FOR /F "tokens=*" %%I IN ('dir *.bat /T:C /O:-D /B') DO SET test=%%I & goto DONE
:DONE

Open in new window

But behind the scenes DOS still does have to read all the files in the directory, filter out just the BAT ones, and then sort by date.  There's no way to get the most recent one "directly".

~bp
0
 
cmntAuthor Commented:
Thanks everyone for their comments. I will go with the FOR...GOTO combination. Regarding the io issue I was a little bit unclear. I wasn't concerned about the Dir command, which I expected to go through the whole directory. I just didn't wanted to iterate through the whole result set.
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

  • 3
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now