Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 批处理脚本,重新格式化cli应用程序的输出_Batch File_Formatting - Fatal编程技术网

Batch file 批处理脚本,重新格式化cli应用程序的输出

Batch file 批处理脚本,重新格式化cli应用程序的输出,batch-file,formatting,Batch File,Formatting,我有一个非常小的批处理脚本,它提取了相当多的文件。 脚本将与压缩数据一起交付给其他用户 现在我的问题是,这个压缩工具正在向cmd窗口输出大量数据。 我认为这会让很多用户感到困惑,因为输出实际上是“正在运行的”。它基本上显示了每一行的百分比,以及如何以何种速度(CPU和HDD)解压缩。 很多令人困惑的数据,没有人需要看到。现在我真的不喜欢抑制程序的所有输出,在我看来,向用户反馈解压已经达到的程度是很重要的。 那么,是否有可能重定向输出,只读取输出的前三位数字,并在一行中将其发送给用户?因此,用户只

我有一个非常小的批处理脚本,它提取了相当多的文件。 脚本将与压缩数据一起交付给其他用户

现在我的问题是,这个压缩工具正在向cmd窗口输出大量数据。 我认为这会让很多用户感到困惑,因为输出实际上是“正在运行的”。它基本上显示了每一行的百分比,以及如何以何种速度(CPU和HDD)解压缩。 很多令人困惑的数据,没有人需要看到。现在我真的不喜欢抑制程序的所有输出,在我看来,向用户反馈解压已经达到的程度是很重要的。 那么,是否有可能重定向输出,只读取输出的前三位数字,并在一行中将其发送给用户?因此,用户只看到一个前进percange(在一行),而不是20个新的行与所有这些数据每秒

下面是一个目前情况的示例:
压缩工具是SREP,我的OS Win 7 x64。

这里是一个简单的混合批处理/JScript脚本,我认为它可以满足您的需要

show3.bat

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

::: Batch part ::::
@cscript //nologo //e:JScript "%~f0"
@exit /b

*** JScript part ***/
while( !WScript.StdIn.AtEndOfStream ) {
  WScript.StdOut.Write( '\x08\x08\x08' + WScript.StdIn.ReadLine().substr(0,3) );
}
WScript.StdOut.WriteLine();
用法:

该脚本可以简化为纯JScript,但使用起来并不方便:

show3.js

while( !WScript.StdIn.AtEndOfStream ) {
  WScript.StdOut.Write( '\x08\x08\x08' + WScript.StdIn.ReadLine().substr(0,3) );
}
WScript.StdOut.WriteLine();
用法:


编辑正如jeb评论的那样,使用此解决方案不需要任何redist

我在jeb的回答中采用了一些概念,并将整个过程合并到一个混合脚本中。不需要独立的“show3”文件

yourCommand
将是您正在使用的任何压缩命令。根据您的评论,如果要将输出打印到stderr而不是stdout,则听起来您可能必须使用
yourCommand 2>&1

我创建了一个“yourCommand.bat”文件用于测试。它粗略地模拟了您为压缩程序描述的输出行为

@echo off
for /l %%A in (1 1 100) do (
  echo %%A   "I don't want to see this quoted text"
  for /l %%B in (1 1 50000) do rem
)
最后,如果你真的想要一个纯批量的解决方案,我大大简化了jeb的解决方案。我删除了临时文件,改为使用管道

@echo off
if "%~1"==":show3" goto :show3
REM whatever batch code you need goes here

(yourCommand & echo EOF) | "%~f0" :show3

REM whatever batch code you need goes here
exit /b

:show3
setlocal enableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
:read
set "ln="
set /p "ln="
if not defined ln goto :read
for /f "tokens=1* delims= " %%A in ("!ln!") do if "%%A%%B" equ "EOF" (
  echo(
  exit /b
)
<nul set /p "=!ln:~0,3!   !cr!"
goto :read
@echo关闭
如果“%~1”==”:show3“转到:show3”
REM您需要的任何批处理代码都会显示在这里
(yourCommand&echo EOF)|“%~f0”:show3
REM您需要的任何批处理代码都会显示在这里
退出/b
:show3
setlocal enableDelayedExpansion
对于('copy/Z'%~dpf0“nul')中的/f%%a,请设置“CR=%%a”
:读
设置“ln=”
设置/p“ln=”
如果在转到中未定义:读取
对于/f“tokens=1*delims=“%%A in(“!ln!”)如果“%%A%%B”等于“EOF”,则执行该操作(
回音(
退出/b
)

如果您使用windows批处理,这是可以做到的,但这并不简单,因为您通常会使用FOR/F循环来实现这一点

类似于(
7z packit…
)中的
for/f“delims=“%%a做…

这里的问题是,for循环将首先收集所有数据并等待
7z
结束,然后再处理任何一行输出

唯一的方法是重定向输出,并同时扫描它。
但要做到这一点,您需要第二个线程(最多在同一个cmd窗口中)

像这样的东西就行了

@echo off
echo start
setlocal EnableDelayedExpansion
if "%1"=="internal" goto :readThread
start /b cmd /c ""%~f0" internal"

rem *** myPacker pack here and redirect the output
del archive.7z
del output.tmp
start "title" /b /wait cmd /c  "%ProgramFiles%\7-Zip\7z" u  archive \tempx\*.rtf \tempx\*.pdf ^> output.tmp
echo EOF>>output.tmp
echo ENDE
:waitForEnd
(
> lock (
  rem
) || goto :waitForEnd
) 2> nul
exit /b

:readThread

for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
echo ####!cr!x
echo(
<output.tmp ( 
    echo ## before
    call :readData 2> lock
    echo after
)
exit /b

:readData
set "var="
set /p var=
if "!var!"=="EOF" exit /b
if defined var (
  <nul set /p ".=Processing files, currently at !var:~0,4!!CR!"
)
goto :readData
@echo关闭
回声启动
setlocal EnableDelayedExpansion
如果“%1”=“内部”转到:readThread
启动/b命令/c“%~f0”内部
rem***我的打包机在此打包并重定向输出
del archive.7z
del output.tmp
启动“title”/b/wait cmd/c“%ProgramFiles%\7-Zip\7z”u archive\tempx\*.rtf\tempx\*.pdf^>output.tmp
echo EOF>>output.tmp
埃科恩德
:waitForEnd
(
>锁(
雷姆
)| |后藤:waitForEnd
)2>nul
退出/b
:readThread
对于('copy/Z'%~dpf0“nul')中的/f%%a,请设置“CR=%%a”
echo###########!cr!x
回音(
锁
呼应
)
退出/b
:readData
设置“var=”
集合/p变量=
如果“!var!”==“EOF”退出/b
如果定义了var(

命名你运行脚本的操作系统,命名压缩工具。一旦你这么做了,你应该会很快得到一个具体的答案。Windows 7和SREP,但我认为jeb的答案正在做这项工作:)我同意:-D这个网站上的人很聪明。Hip,Hip+1代表jeb!+1,这令人印象深刻…而且很疯狂:-)在退出之前添加
del output.tmp
将是一个很好的收尾。哇,太棒了!非常感谢!好的,我有一个问题。我正在努力理解整个脚本(我仍然是批处理脚本的新手),从“rem…”到“.exit/b”的第一个块只是7zip的打包过程,对吗?我将永远不会包装的东西与批次,所以我可以safley删除该部分?我试着用srep.exe(我的归档程序)data.arc.srep替换7zip部分,批量解压归档文件,但我仍然得到程序输出。我猜这是因为程序的输出被认为是错误代码?例如,我只能使用>nul 2>&1将其静音。@Paul Green-Yes from
rem..
to
start 7zip
这是打包代码,在那里您可以使用类似于
start“title”/b/wait cmd/c“srep.exe”的东西…^>output.tmp 2^>^&1
。但是您需要
echo EOF>>output.tmp
处的行作为读卡器线程的结束信号,锁等待读卡器线程的结束。啊,对了。我有点糊涂了。删除档案的del命令把我弄糊涂了。所以我现在有了
start“title”/b/wait cmd/c srep.exe data.arc.srep^>output.tmp 2^>^&1
。但我没有在atm机上打印任何东西,我肯定我遗漏了什么。我对此表示怀疑,但以防万一,我是否需要在其他任何地方添加
2^>^&1
?output.tmp从程序中获取输出,因此它肯定能工作。非常感谢,我也会保存这个答案,以便在我可以使用批处理脚本以外的其他东西的情况下使用:)@Paul Green-它也是一个批处理文件!但它是嵌入式jscript代码的混合体,应该可以在WinXP、Vista和Win7上使用,真的吗?所以用户不需要额外的redist吗?@Paul-试试看,它应该可以正常工作(dbenham的大部分代码都可以正常工作)@PaulGreen-我已经将解决方案压缩成一个单独的版本
@echo off
for /l %%A in (1 1 100) do (
  echo %%A   "I don't want to see this quoted text"
  for /l %%B in (1 1 50000) do rem
)
@echo off
if "%~1"==":show3" goto :show3
REM whatever batch code you need goes here

(yourCommand & echo EOF) | "%~f0" :show3

REM whatever batch code you need goes here
exit /b

:show3
setlocal enableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
:read
set "ln="
set /p "ln="
if not defined ln goto :read
for /f "tokens=1* delims= " %%A in ("!ln!") do if "%%A%%B" equ "EOF" (
  echo(
  exit /b
)
<nul set /p "=!ln:~0,3!   !cr!"
goto :read
@echo off
echo start
setlocal EnableDelayedExpansion
if "%1"=="internal" goto :readThread
start /b cmd /c ""%~f0" internal"

rem *** myPacker pack here and redirect the output
del archive.7z
del output.tmp
start "title" /b /wait cmd /c  "%ProgramFiles%\7-Zip\7z" u  archive \tempx\*.rtf \tempx\*.pdf ^> output.tmp
echo EOF>>output.tmp
echo ENDE
:waitForEnd
(
> lock (
  rem
) || goto :waitForEnd
) 2> nul
exit /b

:readThread

for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
echo ####!cr!x
echo(
<output.tmp ( 
    echo ## before
    call :readData 2> lock
    echo after
)
exit /b

:readData
set "var="
set /p var=
if "!var!"=="EOF" exit /b
if defined var (
  <nul set /p ".=Processing files, currently at !var:~0,4!!CR!"
)
goto :readData