我们如何写一个以&#34结尾的行? 1"使用Windows批处理脚本进入文件?

时间:2013-06-11 10:29:16

标签: batch-file

简短问题

如何使用"foo 1"命令回显字符串echo,同时将其输出重定向到一个文件,以便将整个字符串写入文件?

C:\>echo foo 1>foo.txt

C:\>type foo.txt
foo

C:\>xxd -g1 a.txt
0000000: 66 6f 6f 20 0d 0a                                foo ..

上述实验表明,只有"foo "被写入文件,因为命令中的"1"被解释为重定向运算符1>的一部分。请注意,echo foo 1 > foo.txt不是解决方案,因为它会将"foo 1 "写入文件中,并在字符串中包含不必要的尾随空格。

长问题

请考虑以下Windows批处理脚本。

@echo off
call :log "start script"
call :log "foo"
call :log "end script"
goto :eof

:log
echo %~1>>log.txt
goto :eof

当我执行此脚本时,它的行为符合要求,即在log.txt中写入三行日志。

C:\>foo

C:\>type log.txt
start script
foo
end script

现在考虑以下脚本,其中第二行日志已从"foo"修改为"foo 1"

@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof

:log
echo %~1>>log.txt
goto :eof

这引起了一些惊喜。正如您在下面的输出中看到的,我们在日志文件中看到"foo"而不是"foo 1"

C:\Users\pals3\Desktop>foo

C:\Users\pals3\Desktop>type log.txt
start script
foo
end script

通过从脚本中删除包含@echo off的第一行,然后执行脚本,很容易理解为什么会这样。

C:\>foo.cmd

C:\>call :log "start script"

C:\>echo start script 1>>log.txt

C:\>goto :eof

C:\>call :log "foo 1"

C:\>echo foo  1>>log.txt

C:\>goto :eof

C:\>call :log "end script"

C:\>echo end script 1>>log.txt

C:\>goto :eof

C:\>goto :eof

从这里可以看出,只要脚本中有>>log.txt,命令解释器就会用同义语法1>>log.txt替换它。这意味着我们记录"foo 1"的命令现在以echo foo 1>>log.txt执行,只需将"foo"写入日志文件。

一个简单的解决方案是用echo %~1>>log.txt替换脚本中的语句echo %~1 >>log.txt

@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof

:log
echo %~1 >>log.txt
goto :eof

然而,这意味着每一行日志都会以空格字符为后缀,从迂腐的角度来看这是不理想的,当有人想用grep过滤日志文件时会有点混乱。

C:\>foo

C:\>type log.txt
start script
foo 1
end script

C:\>xxd -g1 log.txt
0000000: 73 74 61 72 74 20 73 63 72 69 70 74 20 0d 0a 66  start script ..f
0000010: 6f 6f 20 31 20 0d 0a 65 6e 64 20 73 63 72 69 70  oo 1 ..end scrip
0000020: 74 20 0d 0a

有没有办法以这样的方式编写:log子例程,以便在没有在每行日志末尾写一个额外的空格时摆脱上面提到的惊喜?

3 个答案:

答案 0 :(得分:5)

尝试使用括号:

@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof

:log
(echo %~1)>>log.txt
goto :eof

答案 1 :(得分:3)

一个鲜为人知的事实是,您可以在命令之前指定重定向

@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof

:log
>>log.txt echo %~1
goto :eof

产生

start script
foo 1
end script

答案 2 :(得分:1)

同样,这可以使用。任何)字符都需要进行转义,但在不需要转义的情况下会导致整齐的阻塞。

(
echo 123
echo %~1
echo 321
)>log.txt