批量回显管道符号导致意外行为

时间:2009-12-06 10:31:08

标签: batch-file

我的批处理文件中有一个变量,它包含管道符号(这一个:|)所以当我回显变量时,我得到一个关于无法识别的内部/外部命令的错误。

我需要一种方法来让它正确地回应它或更好地删除包括|之后的所有内容符号以及它之前的任何额外空格。

6 个答案:

答案 0 :(得分:39)

在Windows批处理文件中使用时,通常必须转义几个特殊字符。以下是部分列表:< > & | ^ %

转义字符为^。所以要获得文字|,你应该这样做:

echo ^|

当特殊字符在变量中时,它变得有点难。但是如果使用特殊语法,则可以替换变量中的字符,如下所示:

set X=A^|B

REM replace pipe character with underscore
set Y=%X:|=_%

echo %Y%
REM prints "A_B"

答案 1 :(得分:5)

你必须逃避|打印var之前的字符。以下打印a | b

@echo off

set x=a^|b
echo %x:|=^|%

答案 2 :(得分:2)

逃避它

echo \|

或用引号括起来

echo "|"

答案 3 :(得分:1)

老问题,但有一个未提及的解决方案,更容易使用:
延迟扩张

使用延迟扩展的好处是,任何内容都可以不加修改地使用,根本没有任何有问题的字符。

set "test=A|B&C,D"E^<F^>G"
setlocal EnableDelayedExpansion
echo !test!

set test       --- Works, but shows also: "test=..."
echo %test% --- This one fails

答案 4 :(得分:0)

var items = (from p in db.JDE_Processes
                             join uuu in db.JDE_Users on p.FinishedBy equals uuu.UserId into finished
                             from fin in finished.DefaultIfEmpty()
                             join uu in db.JDE_Users on p.StartedBy equals uu.UserId into started
                             from star in started.DefaultIfEmpty()
                             join h in db.JDE_Handlings on p.ProcessId equals h.ProcessId into hans
                             from ha in hans.DefaultIfEmpty()
                             where p.TenantId == tenants.FirstOrDefault().TenantId && p.CreatedOn >= dFrom && p.CreatedOn <= dTo
                             group new { p, fin, star, ha }
                             by new {
                                 p.ProcessId,
                                 p.Description,
                                 p.StartedOn,
                                 p.StartedBy,
                                 p.FinishedOn,
                                 p.FinishedBy,
                                 p.PlannedFinish,
                                 p.PlannedStart,
                                 fin.Name,
                                 fin.Surname,
                                 StarterName = star.Name, // <-- Creating alias
                                 StarterSurname = star.Surname // <-- Creating alias
                             } into grp
                             orderby grp.Key.ProcessId descending
                             select new Process
                             {
                                 ProcessId = grp.Key.ProcessId,
                                 Description = grp.Key.Description,
                                 StartedOn = grp.Key.StartedOn,
                                 StartedBy = grp.Key.StartedBy,
                                 StartedByName = grp.Key.StarterName + " " + grp.Key.StarterSurname,
                                 FinishedOn = grp.Key.FinishedOn,
                                 FinishedBy = grp.Key.FinishedBy,
                                 FinishedByName = grp.Key.Name + " " + grp.Key.Surname,
                                 PlannedStart = grp.Key.PlannedStart,
                                 PlannedFinish = grp.Key.PlannedFinish,
                                 HandlingStatus = grp.Where(ph=>ph.ha.IsCompleted == null && ph.ha.HandlingId >0).Count().ToString()
                             });

REM,您应该有无限个管道。两次按CTRL + C Ctrl两次 REM打印“该进程试图写入不存在的管道。”

答案 5 :(得分:0)

Henrik's answer 如果您只是想将变量的内容回显到屏幕上可以正常工作,但是如果您想将包含管道符号的值通过管道传输到另一个程序中(就像我所做的那样),您需要添加更多插入符号 (^):

回显包含管道 (|) 的裸文本:

echo Hello ^| world

包含管道 (|) 的 Set-and-echo 变量:

set txt=Hello ^| world
echo %txt:|=^|%

将包含管道 (|) 的裸文本回显到另一个程序中:

echo Hello ^^^| world | hexdump

产生:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

包含管道 (|) 的 Set-and-echo 变量进入另一个程序

set txt=Hello ^| world
echo %txt:|=^^^|% | hexdump

产生:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

hexdump 只是一个实用程序,我必须以十六进制和 ASCII 格式转储 stdin)。

需要三个插入符号 (^^^) 的原因(我认为我理解它)是因为 CMD 本质上会解析命令行两次:一次是识别它包含一个未转义的管道({{ 1}} 位);然后每个部分在执行它们时被第二次处理

第一遍将 | hexdump 变成 echo Hello ^^^| world(将中间位读为 echo ^| world 后跟 ^^:转义插入符和转义管道)。当它被处理 第二次 时间 - 在执行管道时 - “幸存”插入符号保护管道符号,以便 ^| 被送入下一个命令。