2013-04-05 50 views
5

我在Windows cmd.exe(至少達到XP)中使用了一個非常妙的技巧來模擬不帶換行符的echo -n的UNIX回顯行爲。例如,命令:Windows的「echo -n」不再適用於Win7

<nul: set /p junk= xyzzy 

會產生完全六個字符被輸出,領先的空間和字符串「XYZZY」,而不是其他。

如果你有興趣爲什麼這個作品,它實際上是一個輸入命令,輸出" xyzzy"作爲提示,然後分配該輸入junk環境變量之前等待用戶輸入。在這種特殊情況下,它不會等待用戶輸入,因爲它會從nul設備獲取輸入。

它時,你要列出每行多於一個循環(每個文件一個迭代)(例如)處理文件是cmd腳本相當有用。通過使用這一招,你可以簡單地輸出每個文件名後面加一個空格,沒有換行的話,循環,輸出一個換行符後完成了:

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

現在我發現,Windows 7中,空間下不再輸出,所以我得到的是:

Processing files: 
file1.txtfile42.txtp0rn.zip 

有沒有一種方法,我可以得到set /p重新開始履行我的空間,或有在Win7另一種方式來達到同樣的效果?

我試過報價,使用.(在echo作品),甚至與^逃避串,但沒有人似乎工作:

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 

我需要的是:

C:\Pax> some_magical_command_with_an_argument xyzzy 
xyzzy 

這將給我的空間(S)在開始沒有換行結束。

+2

+1因爲嘗試真的很難在批處理文件中執行任何SANE人員在PERL或PYTHON中執行的操作。 – 2013-04-05 02:44:07

+0

@Warren,不幸的是,政策規定我們只能使用基本Win安裝中可用的內容。所以Perl和Python都不在了,儘管事實上我可以用一半的代碼來完成它:-)我可以用VBScript重寫腳本,但我希望能夠更輕鬆地修復 - 腳本不算小。話雖如此,我可能只是做VBS中的回聲位,所以我可以研究一下。如果你在答案中提出這個問題,我會給你+1,因爲這是你對使用體面語言的評論,這讓我有這種想法。 – paxdiablo 2013-04-05 02:48:22

+0

因此,貴公司不允許用戶使用安裝程序安裝軟件? :-) – 2013-04-05 03:17:43

回答

0

這不是使用set或其他cmd-內部的東西,但您可以使用cscript(也包含在標準的Windows安裝中)來做類似的事情。您甚至可以通過使用創建臨時文件vbs來從cmd文件本身(無需單獨維護文件)控制它。

將此代碼放在您的cmd文件:

rem Create the VBS file to output spaces and a word. 

echo.for i = 1 to WScript.Arguments.Item(0) >spacetext.vbs 
echo.  WScript.StdOut.Write ^" ^" >>spacetext.vbs 
echo.next >>spacetext.vbs 
echo.WScript.StdOut.Write WScript.Arguments.Item(1) >>spacetext.vbs 

rem Do this once per word you want output (eg, in a loop). 

cscript /nologo spacetext.vbs 0 Hello, 
cscript /nologo spacetext.vbs 1 my 
cscript /nologo spacetext.vbs 1 name 
cscript /nologo spacetext.vbs 1 is 
cscript /nologo spacetext.vbs 4 Pax. 

rem Do this at the end to add newline and kill temp file. 

echo. 
del spacetext.vbs 

的這個輸出是你所期望的:

Hello, my name is Pax. 
0

OK,現在有正確的答案是:你不能有一個在Win7中導致<space>set /p。有Windows版本之間的差異:

Syntax    | XP         | Vista and Windows 7 
----------------------+-------------------------------------+------------------------------------- 
<nul set /p =!msg! |- If 1st char is quote, then trims |- Trims leading white space chars. 
     or    | that quote, and if at least one |- If 1st non white space char is  
<nul set /p "=!msg!" | additional quote, than trims last | quote, then that quote is treated 
         | quote and all remaining chars.  | as white space and trimmed, and if 
         |- If 1st non trimmed char is =, then | at least one additional quote, then 
         | syntax error.      | trims last quote and all remaining 
         |          | chars. 
         |          |- If 1st non trimmed char is =, then 
         |          | syntax error. 
----------------------+-------------------------------------+------------------------------------- 
<nul set /p ="!msg!" |- Trims leading control chars and |- Trims leading white space chars. 
     or    | spaces.       |- If 1st non trimmed char is =, then 
<nul set /p "="!msg!""|- If 1st non trimmed char is =, then | syntax error. 
         | syntax error.      | 
----------------------+-------------------------------------+------------------------------------- 

On Vista and Windows 7, the trimmed leading white space chars are: 
    9 0x09 Horizontal Tab 
    10 0x0A New Line 
    11 0x0B Vertical Tab 
    12 0x0C Form Feed 
    13 0x0D Carriage Return 
    32 0x20 Space 
    255 0xFF Non-breaking Space 

source

對於其他技術來獲得前導空格在純批次看到here

0

你的意思是這樣嗎?

@ECHO OFF 
SETLOCAL 
FOR /l %%i IN (1,1,4) DO <NUL SET /p var="item %%i " 

結果:

項目1項2項3項4

還是你絕對堅持在開始的空間?

1

這與paxdiablo的答案非常相似,除了我使用混合JScript /批處理文件而不是臨時VBScript文件。

我的腳本被稱爲jEval.bat - 它只是評估任何有效的JScript表達式並將結果寫入標準輸出,可選地帶有尾隨換行符。這個愚蠢的小腳本對批量編程非常有用。

假設jEval.bat或者是在當前文件夾,或介於PATH中,那麼你可以簡單地這樣做:

call jeval "' xyzzy'" 

這裏是腳本。它確實非常簡單。大部分代碼與文檔,錯誤處理和內置的幫助系統有關。

@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))); 
}