在命令行中指定文件名时,以下脚本运行良好。
tail.bat@echo off
set "COUNT=%1"
set "COUNT=%COUNT:-=%"
set "FILENAME=%~2"
powershell "Get-Content %FILENAME% -Last %COUNT%"
但是,我需要的是能够将文本从stdin传递到Get-Content
。我想编写以下内容以获取分配给项目的最后三个Subversion标记。我可以做些什么来使Get-Content
的源成为标准输入?
svn ls svn://ahost/arepo/aproject/tags | call tail.bat -3
注意:我不允许从外部安装任何有用的工具,例如tail
。必须使用机器上已有的程序完成。
更新
@ mklement0提供了答案。从那时起,我添加了代码,如果没有提供,则默认COUNT值为10。这符合UNIX / Linux方式。
@echo off
SET "COUNT=%~1"
IF "%COUNT:~0,1%" == "-" (
SET "COUNT=%COUNT:~1%"
SHIFT
) ELSE (
SET "COUNT=10"
)
SET "FILENAME=%~1"
if "%FILENAME%" == "" (
powershell -noprofile -command "$Input | Select-Object -Last %COUNT%"
) else (
powershell -noprofile -command "Get-Content \"%FILENAME%\" -Last %COUNT%"
)
EXIT /B
答案 0 :(得分:7)
重写tail.bat
如下:
@echo off
set "COUNT=%1"
set "COUNT=%COUNT:-=%"
set "FILENAME=%~2"
if "%FILENAME%"=="" (
powershell -noprofile -command "$Input | Select-Object -Last %COUNT%"
) else (
powershell -noprofile -command "Get-Content \"%FILENAME%\" -Last %COUNT%"
)
如果没有传递文件名参数,这将使PowerShell通过$Input
读取stdin输入,由this answer提供。
示例:
C:> (echo one & echo two & echo three) | tail.bat -2
two
three
注意:
虽然PowerShell通常通过管道发送并输出任何类型的对象,但它与外部世界的接口总是涉及字符串< / EM> 强>
因此,假设 $Input
是枚举器,代表外部 stdin输入,我们可以肯定它逐个枚举输入文本行(作为字符串),所以我们只需选择感兴趣的行,这就是为Select-Object
提供管道的原因已经足够了。
相比之下,在PowerShell中按名称读取文件需要Get-Content
(顺便提一下,它也会逐个通过管道发送输入文件的行,除非你也指定-Raw
);由于Get-Content
内置了tail
功能,通过参数-Tail
(及其别名-Last
),这就是所需要的。
CAVEAT :当PowerShell与外界交谈时,涉及输入上的字符解码和输出上的重新编码:
如果您只处理ASCII编码输入(代码点介于0到127之间的单字节字符),您无需担心。
否则,为痛苦的世界做好准备 - 详见下文。
解码/重新编码问题
假设PowerShell识别出输入编码(见下文),输出编码总是 控制台窗口分配的编码是;不幸的是,默认情况下,这是OEM代码页(例如,美国 - 英语系统上的“DOS”代码页CP437),在PS中反映为[Console]::OutputEncoding
。
因此,使用正确识别的输入,如果您打印到控制台,事情看起来会很好,但如果您在文件中捕获输出,最终会得到一个OEM代码页编码的文件,这可能是不受欢迎的。
如果可行,您可以从根本上设置控制台窗口以使用您选择的代码页(输入和输出编码)(使用chcp
),但遗憾的是,尝试更改脚本中的编码 ad-hoc 不是一种选择。
请注意,使用UTF-8 - 代码页65001
- 仅在将控制台窗口配置为使用TT(TrueType)字体之一时才有效。
如上所述,基于默认输入编码(也是OEM代码页,反映在PS中),正确识别的输入编码集不幸地限于以下内容为[Console]::InputEncoding
;请记住:输入将在输出上重新编码:
Unicode
,需要重新编码为输出上可能不同的内容)< / LI>
默认情况下的代码页编码),但对 stdin 输入执行相同操作(如-Encoding <enc>
中所反映的那样)将是非常重要的。
Get-Content
编码):$Input