我有一个执行任务的批处理脚本并将输出发送到文本文件。有没有办法在控制台窗口上显示输出?
例如:
c:\Windows>dir > windows-dir.txt
有没有办法让dir
的输出显示在控制台窗口中,并将其放入文本文件中?
答案 0 :(得分:209)
不,你不能用纯粹的重定向 但是你可以使用一些技巧(比如tee.bat)。
我尝试稍微解释重定向。
您使用>重定向十个流中的一个档案或<文件
如果重定向在命令之前或之后,它是不重要的,
所以这两行几乎相同。
dir > file.txt
> file.txt dir
此示例中的重定向只是 1> 的快捷方式,这意味着将重定向流1(STDOUT)。 因此,您可以使用前面的数字重定向任何流,例如 2> err.txt ,也允许在一行中重定向多个流。
dir 1> files.txt 2> err.txt 3> nothing.txt
在此示例中,“standard output”将进入files.txt,所有错误都将出现在err.txt中,stream3将进入nothing.txt(DIR不使用流3)。
Stream0是STDIN
Stream1是STDOUT
Stream2是STDERR
未使用Stream3-9
但是如果您尝试多次重定向同一个流会发生什么?
dir > files.txt > two.txt
“只能有一个”,它始终是最后一个! 所以它等于 dir> two.txt 强>
好的,还有一种可能性,即将流重定向到另一个流。
dir 1>files.txt 2>&1
2>& 1 将stream2重定向到stream1, 1> files.txt 将所有内容重定向到 files.txt 。
订单在这里很重要!
dir ... 1>nul 2>&1
dir ... 2>&1 1>nul
是不同的。第一个将所有(STDOUT和STDERR)重定向到NUL,
但第二行将STDOUT重定向到NUL和STDERR为“空”STDOUT。
作为一个结论,很显然为什么OtávioDécio和andynormancx的例子无效。
command > file >&1
dir > file.txt >&2
两者都尝试重定向stream1两次,但“只能有一个”,并且它始终是最后一个。
所以你得到了
command 1>&1
dir 1>&2
在第一个示例中,不允许将stream1重定向到stream1(并且不是很有用)。
希望它有所帮助。
答案 1 :(得分:32)
以这种方式使用Windows版本的UNIX tee命令(从http://unxutils.sourceforge.net找到):
mycommand > tee outpu_file.txt
如果您还需要STDERR输出,请使用以下内容
2>&1
将STDERR输出组合成STDOUT(主流)。
mycommand 2>&1 | tee output_file.txt
答案 2 :(得分:9)
如果您不需要实时输出(即程序正在编写),您可以添加
type windows-dir.txt
之后。
答案 3 :(得分:7)
对我有用的解决方案是:dir > a.txt | type a.txt。
答案 4 :(得分:6)
是的,有一种方法可以在控制台(屏幕)和文件中显示单个命令输出。使用您的示例,使用...
@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt
详细说明:
FOR
命令将命令或文本的输出解析为变量,可以多次引用该变量。
对于命令,例如DIR /B
,请用单引号括起来,如下例所示。用您想要的命令替换DIR /B
文本。
FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT
要显示文本,请将文本用双引号括起来,如下例所示。
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT
......还有换行......
FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
ECHO %%I & ECHO %%I>>FILE.TXT
)
如果您有时希望仅在控制台(屏幕)上输出,而其他时间只发送到文件,并且其他时间发送到两者,请使用变量指定FOR循环的“DO”子句,如图所示以下%TOECHOWHERE%
。
@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
FOR %%J IN (TRUE FALSE) DO (
SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish
:Runit
REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
REM above when the FOR loops are evaluating the first item in the list,
REM "TRUE". So, the first value of TOSCREEN is "TRUE " (with a trailing
REM space), the second value is "FALSE" (no trailing or leading space).
REM Adding the ": =" text after "TOSCREEN" tells the command processor to
REM remove all spaces from the value in the "TOSCREEN" variable.
IF "%TOSCREEN: =%"=="TRUE" (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=On screen, and in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
) ELSE (
SET TEXT=On screen, not in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I"
)
) ELSE (
IF "%TOFILE: =%"=="TRUE" (
SET TEXT=Not on screen, but in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>>FILE.txt"
) ELSE (
SET TEXT=Not on screen, nor in "FILE.TXT"
SET TOECHOWHERE="ECHO %%I>NUL"
)
)
FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof
:Finish
ECHO Finished [this text to console (screen) only].
PAUSE
答案 5 :(得分:3)
command > file >&1
答案 6 :(得分:2)
如果要追加而不是替换输出文件,可能需要使用
if ($this->request->is('post')) {
$filter_url['controller'] = $this->request->params['controller'];
$filter_url['action'] = $this->request->params['action'];
$filter_url['page'] = 1;
// for each filter we will add a GET parameter for the generated url
foreach($this->request->data as $name => $value){
if($value){
$filter_url[$name] = urlencode($value);
}
}
//Post params are now GET paramaters
return $this->redirect($filter_url);
}
debug($this->request->params['pass'] ); //outputs nothing
foreach($this->request->params['pass'] as $param_name => $value):
// debug($param_name);
// debug($value);
if ($param_name=='lastname') $searchLastName =$value;
if ($param_name=='firstname') $searchFirstName =$value;
endforeach;
//view
<?php echo $this->Form->create(); ?>
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<td><?php echo $this->Form->input('firstname',['label' => 'FirstName']); ?></td>
<td><?php echo $this->Form->input('lastname',['label' => ' LastName']); ?></td>
<td> <?php //echo $this->Form->button('Submit Form', ['name'=>'search','type' => 'submit']); ?></td>
</tr>
</thead>
<?= $this->Form->button('Submit Form', ['name'=>'search','type' => 'submit']); ?>
<?= $this->Form->end() ?>
http://book.cakephp.org/3.0/en/controllers/request-response.html
或
var you = items.Where(x=>x.Id == myId).FirstOrDefault();
var allAbove = items.Where(x=>x.Id!=you.Id)
.Where(x=>x.TotalPoint>you.TotalPoints || x.CorrectTrends>you.CorrectTrends);
答案 7 :(得分:1)
我喜欢atn的回答,但对我来说下载wintee并不是一件轻而易举的事,Displaying Windows command prompt output and redirecting it to a file也是开源的,只提供了tee功能(如果你只想要tee而不是整套unix,那就很有用公用事业)。我从davor对{{3}}的回答中了解到了这一点,在那里你也可以找到对unix实用程序的引用。
答案 8 :(得分:1)
我的选择是:
创建一个接收消息的子例程,并自动将其发送到控制台和日志文件。
setlocal
set logfile=logfile.log
call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"
goto :eof
:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b
如果在邮件中添加变量,请务必在将其发送到子例程之前删除其中的引号,否则可能会导致批处理。 当然这只适用于回声。
答案 9 :(得分:1)
我制作了一个简单的C#控制台,它可以处理cmd屏幕和日志的实时输出
class Tee
{
static int Main(string[] args)
{
try
{
string logFilePath = Path.GetFullPath(args[0]);
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
for (int value; (value = Console.In.Read()) != -1;)
{
var word = Char.ConvertFromUtf32(value);
Console.Write(word);
writer.Write(word);
}
}
}
catch (Exception)
{
return 1;
}
return 0;
}
}
批处理文件的使用方法与使用Unix tee
foo | tee xxx.log
这是包含Tee.exe的存储库,以防您无法编译工具 https://github.com/iamshiao/Tee
答案 10 :(得分:0)
“Tomas R”提供的解决方案非常适合OP的问题,并且本机可用。
尝试: chkdsk c:&gt; output.txt |输入output.txt
该命令的输出涉及一个完整的百分比,它被串行输出到文件,因此它看起来有点乱(即文本将随着它的进展而附加)。输出到STDOUT(屏幕)的位不会发生这种情况。如果你只是在没有重定向的情况下执行相同的命令,那就是这样。