Multi line variable pipe

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
lysp
Posts: 4
Joined: 05 Aug 2015 23:48

Multi line variable pipe

#1 Post by lysp » 05 Aug 2015 23:55

I'm trying to redirect a multi line variable that I build in a for-loop into an external program that takes either a text file or a pipe input.

The result I'm getting seems to be a common problem where only the first line gets passed through the pipe.

Are they any hacks that I can do be able to echo/output the multi-line variable into a pipe?

Example:

Code: Select all

@echo off
setlocal enableDelayedExpansion
set NL=^


rem leave empty lines
set var=444!NL!222!NL!111!NL!444!NL!000

echo !var! | sort /r


An alternative is to put the variable into single line array variables and loop the echos, but still need it somehow combined into a single pipe.

I can't just do multiple echo's ie (echo %var1% & echo %var2%, etc), as the number of lines can be anywhere from 2 to thousands of lines.

I'm currently doing this through a temp file, but would like to avoid this to make it cleaner if possible.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Multi line variable pipe

#2 Post by foxidrive » 06 Aug 2015 01:10

lysp wrote:I'm trying to redirect a multi line variable that I build in a for-loop into an external program that takes either a text file or a pipe input.

the number of lines can be anywhere from 2 to thousands of lines.


You will run into a brick wall with the length of the variable.

See here: viewtopic.php?f=3&t=6108

The exact details of the task can change the solution.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Multi line variable pipe

#3 Post by jeb » 06 Aug 2015 01:56

Hi lysp,

there is no problem with the pipe at all, it's your echo :!:

First try it with

Code: Select all

set var | sort /r

And you get
output wrote:var=444
444
222
111
000


It works with the correct output, but echo !var! doesn't work, as in the batch file the !var! will be expanded, but then it will be transfered to a new cmd.exe instance and parsed again.
But there are raw linefeeds in the special characters and therefore the tail of the line will be removed.

You can use a more complicated form of the linefeeds or simply expand the variable in the new cmd instance.

Code: Select all

(cmd /v:on /c echo !var!)  | sort /r

The brackets are important :!:
Without the brackets it would fail for the same reasons, but with brackets the delayed expansion will be supressed in the batch context.

lysp
Posts: 4
Joined: 05 Aug 2015 23:48

Re: Multi line variable pipe

#4 Post by lysp » 06 Aug 2015 02:49

If there is an issue with variable length then I'm guessing the file will be the only solution then.

What I'm doing is generating a download list and piping it through aria2c (a unix multi-file downloader ported to win32).

The file format is a url and a secondary line to give it a name:

Code: Select all

https://www.server.com/asd/dassdasdasda/sdasdasda/sdasda/file?auth=3219238019023190231902312390902319023190231klsdfaklsdfklsdf&tag=123902319023190231
  out=file1.bin
https://www.server.com/asd/dassdasdasda/sdasdasda/sdasda/file?auth=3219238019023190231902312390902319023190231klsdfaklsdfklsdf&tag=123902319023190231
  out=file2.bin
https://www.server.com/asd/dassdasdasda/sdasdasda/sdasda/file?auth=3219238019023190231902312390902319023190231klsdfaklsdfklsdf&tag=123902319023190231
  out=file3.bin
https://www.server.com/asd/dassdasdasda/sdasdasda/sdasda/file?auth=3219238019023190231902312390902319023190231klsdfaklsdfklsdf&tag=123902319023190231
  out=file4.bin


Due to the urls having authentication tokens on them, the urls are very large.

File may be from 50k -> 500k.

Guessing then the file is my only choice..
Last edited by lysp on 06 Aug 2015 03:12, edited 1 time in total.

lysp
Posts: 4
Joined: 05 Aug 2015 23:48

Re: Multi line variable pipe

#5 Post by lysp » 06 Aug 2015 02:59

Hi.

Code: Select all

(cmd /v:on /c echo !var!)  | sort /r


Thanks for that.

That works great, but as per my post above it looks like I may start to get to issues with variable length.

There are some cases where I can probably use that in future.

One other follow up question, is there a way to pipe an array out also?

eg.

Code: Select all

set temp[1]=1111
set temp[2]=2222
set temp[3]=5555
set temp[4]=3333

for /L %%a in (1,1,4) do (echo !temp[%%a]!)


How would i pipe that to a sort for example? Basically eliminate the intermediary multi line variable?

That might get past the variable length issue by pushing it all through as I build the stdout.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Multi line variable pipe

#6 Post by jeb » 06 Aug 2015 03:18

lysp wrote:One other follow up question, is there a way to pipe an array out also?


Quite simple :wink:

Code: Select all

set temp[1]=1111
set temp[2]=2222
set temp[3]=5555
set temp[4]=3333

(
  for /L %%a in (1,1,4) do @(
    cmd /v:on /c echo !temp[%%a]!
  )
) | sort


But it could be easier to start a new batch (or the same batch) for the output, as command blocks with pipes and delayed expansion can be sometimes a bit surprisingly.
Why does delayed expansion fail when inside a piped block of code?

Code: Select all

@echo off
if "%~1"==":output" goto :output

set "temp[1]=1111"
set "temp[2]=2222"
set "temp[3]=5555"
set "temp[4]=3333"

"%~f0" :output | sort
exit /b

:output
setlocal EnableDelayedExpansion
for /L %%n in (1 1 4) DO (
    echo(!temp[%%n]!
)
exit /b

lysp
Posts: 4
Joined: 05 Aug 2015 23:48

Re: Multi line variable pipe

#7 Post by lysp » 06 Aug 2015 03:52

Fantastic.

Definitely gives me something to bite my teeth into.

Thanks for your help.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Multi line variable pipe

#8 Post by Aacini » 06 Aug 2015 06:38

This method work also: 8)

Code: Select all

@echo off

set temp[1]=1111
set temp[2]=2222
set temp[3]=5555
set temp[4]=3333

(
   cmd /v:on /c "for /L %%a in (1,1,4) do @echo !temp[%%a]!"
) | sort

EDIT: Even simpler! :mrgreen:

Code: Select all

(for /F "tokens=1* delims==" %%a in ('set temp[') do @echo %%b) | sort

Antonio

Post Reply