Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows equivalent of "echo -n" no longer works in Win7

Tags:

windows

cmd

I had a nifty trick in Windows cmd.exe (at least up to XP) to emulate the behaviour of the UNIX echo without a newline, echo -n. For example, the command:

<nul: set /p junk= xyzzy

would result in exactly six characters being output, the leading space and the string "xyzzy", and nothing else.

If you're interested in why this works, it's actually an input command which outputs " xyzzy" as the prompt then waits for user input before assigning that input to the junk environment variable. In this particular case, it doesn't wait for user input since it grabs the input from the nul device.

It was rather useful in cmd scripts when (for example) processing files in a loop (one iteration per file) where you want to list more than one per line. By using this trick, you could simply output each file name followed by a space and no newline then, after the loop, output a newline to finish up:

Processing files:
    file1.txt file42.txt p0rn.zip

Now I discover that, under Windows 7, the spaces are no longer output so what I get is:

Processing files:
file1.txtfile42.txtp0rn.zip

Is there a way I can get set /p to start honouring my spaces again, or is there another way in Win7 to achieve the same effect?

I've tried quoting, using . (which works in echo) and even escaping the string with ^, but none of them seem to work:

C:\Pax> <nul: set /p junk= xyzzy
xyzzy

C:\Pax> <nul: set /p junk=" xyzzy"
xyzzy

C:\Pax> <nul: set /p junk=' xyzzy'
' xyzzy'

C:\Pax> <nul: set /p junk=. xyzzy
. xyzzy

C:\Pax> <nul: set /p junk=^ xyzzy
xyzzy

What I need is:

C:\Pax> some_magical_command_with_an_argument xyzzy
 xyzzy

which will give me the space(s) at the start and no newline at the end.

like image 659
paxdiablo Avatar asked Nov 13 '22 08:11

paxdiablo


1 Answers

This is very similar to paxdiablo's answer, except I use a hybrid JScript/batch file instead of a temporary VBScript file.

My script is called jEval.bat - and it simply evaluates any valid JScript expression and writes the result to stdout, optionally with a trailing newline. The silly little script is extremely useful for batch programming.

Assuming jEval.bat is either in your current folder, or somewhere in your PATH, then you can simply do something like:

call jeval "' xyzzy'"

Here is the script. It really is very simple. Most of the code is related to documentation, error handling, and a built in help system.

@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment

::************ Documentation ***********
:::
:::jEval  JScriptExpression  [/N]
:::jEval  /?
:::
:::  Evaluates a JScript expression and writes the result to stdout.
:::
:::  A newline (CR/LF) is not appended to the result unless the /N
:::  option is used.
:::
:::  The JScript expression should be enclosed in double quotes.
:::
:::  JScript string literals within the expression should be enclosed
:::  in single quotes.
:::
:::  Example:
:::
:::    call jEval "'5/4 = ' + 5/4"
:::
:::  Output:
:::
:::    5/4 = 1.25
:::

::************ Batch portion ***********
@echo off

if "%~1" equ "" (
  call :err "Insufficient arguments"
  exit /b
)
if "%~2" neq "" if /i "%~2" neq "/N" (
  call :err "Invalid option"
  exit /b
)
if "%~1" equ "/?" (
  setlocal enableDelayedExpansion
  for /f "delims=" %%A in ('findstr "^:::" "%~f0"') do (
    set "ln=%%A"
    echo(!ln:~3!
  )
  exit /b
)
cscript //E:JScript //nologo "%~f0" %*
exit /b

:err
>&2 echo ERROR: %~1. Use jeval /? to get help.
exit /b 1


************ JScript portion ***********/
if (WScript.Arguments.Named.Exists("n")) {
  WScript.StdOut.WriteLine(eval(WScript.Arguments.Unnamed(0)));
} else {
  WScript.StdOut.Write(eval(WScript.Arguments.Unnamed(0)));
}
like image 118
dbenham Avatar answered Nov 15 '22 06:11

dbenham