当“IF”比较在管道块命令中时,为什么会出现错误消息?

时间:2016-04-21 08:20:00

标签: batch-file if-statement cmd io-redirection

我简化了代码。 以下三个是工作。

for /L %a in (1,1,9) do @(if %a NEQ 0 (echo %a))

&安培;

for /L %a in (1,1,9) do @(if not %a == 0 (echo %a))

&安培;

(for /L %a in (1,1,9) do @(if not %a == 0 (echo %a)))|sort /R

但下一个没有用,

(for /L %a in (1,1,9) do @(if %a NEQ 0 (echo %a)))|sort /R

管道阻止命令中NEQ的问题是什么?

更简化,

这有效,(if 3 == 3 echo yes)|sort

这不起作用,(if 3 NEQ 2 echo yes)|sort

我的部分代码。

@echo off
setlocal enabledelayedexpansion
set Unx_path=.....\bin\UnxUtils\
(
for /F %%a in ('^""%Unx_path%pclip.exe"^|"%Unx_path%sed.exe" -r "s/^^$/none/"^|"%Unx_path%sed.exe" -rf "script_file"^"') do @(
  if not "%%a" == "none" (
    "%Unx_path%grep.exe" -iEe "%%a" "file4search"|"%Unx_path%sed.exe" -r "s/^^[^,]+$/,&/";"s/^^([^.]+)[.][^.]+$/\1/"|"%Unx_path%gawk.exe" "BEGIN{FS=\",\";ORS=\" \"}{print $2}"|"%Unx_path%sed.exe" "s/%%a//I g";"s/.*/%%a &|/";"s/ -/ /g";"s/ |/\n/g";"s/ /\t/g";"s/~/\t/g"
  ) else (
    echo none
  )
)
)|"%Unx_path%gclip.exe"
exit /b

4 个答案:

答案 0 :(得分:3)

试试这个:

set "myline=if 3 NEQ 2 echo yes"

( %myLin^e%)|sort

或从批处理文件(双重扩展与批处理文件和控制台的工作方式不同):

set "myline=if 3 NEQ 2 echo yes"

( %%myLine%%)|sort

"神秘"由jeb herehere解决。虽然您在管道之前遇到了问题,但它是同一个错误,因为cmd在管道的每一侧都创建了两个线程。

这里是如何使for循环起作用的:

set "line=if %a NEQ 0"
(for /L %a in (1,1,9) do @( %lin^e% echo %a))|sort /R

答案 1 :(得分:3)

出于测试目的,可以使用cmdcmdline变量 但是,当表达式中的某个地方出现语法错误时,这会失败,因为完整的代码块将被删除。

@echo off
echo dummy | (
echo %%cmdcmdline%
if 1 NEQ 2 echo Work
)

这导致"2" can't be syntactically evaluated here(来自德国"2" kann syntaktisch an dieser Stelle nicht verarbeitet werden.

因此,在语法错误的情况下,您无法查看原因!

我为这种情况构建一个小的调试变量

@echo off
setlocal
(set \n=^
%=empty=%
)
set "debug=echo ### %%cmdcmdline%% ^) %%\n%%"
echo dummy | (
    %debug%
    if 1 NEQ 2 echo Work
)

当您添加%debug%时,您将看到cmdcmdline,但代码将不会被执行,因此您可以检查不同的修改如何生效。

喜欢

...
| ( 
  %debug%
  break & if 1 NEQ 2 echo THIS FAILS
)

...
| ( 
  %debug%
  break ^& if 1 NEQ 2 echo This Works !!!
)

诀窍是添加^) %%\n%%,这将使用)关闭调试表达式代码块,并取消通过换行符%%\n%%进一步解析重映射代码。

答案 2 :(得分:3)

基于这个想法&来自npocmaka&的方法杰布。

另一种方法是在管道代码中解决 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/home" android:scaleType="fitXY" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="1" android:layout_gravity="bottom" android:minHeight="250dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:minHeight="125dp"> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 1" android:layout_gravity="center" /> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Button 2" /> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:minHeight="125dp"> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 3" android:layout_gravity="center" /> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Button 4" /> <Space android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout> </GridLayout> </LinearLayout> </RelativeLayout> 命令的错误。

在正确位置添加ESCAPE空间

对于IF EQU NEQ LSS LEQGTR

  1. ONE ^ 必须在第1次比较后添加GEQ

  2. ^ string/number EQU {之间必须至少添加 TWO SPACE {1}} NEQ LSSLEQ

  3. 实施例,

    GTR

    GEQ可以替换为echo pipe|IF 1234^ GTR 124 echo true 以查看解析器。

    true

    %^cmdcmdline%&amp; (IF 1234^ NEQ 124 echo right)|more

    1. 至少 ONE SPACE 必须在IF DEFINEDIF EXIST之后添加,
    2. 至少 TWO SPACE 必须在IF DEFINEDIF EXIST之前添加
    3. ONE ^ 必须在上面添加的 SPACE 之间添加。
    4. 实施例,

      variable

      file/folder可以替换为echo pipe|IF DEFINED ^ username echo true echo pipe|IF EXIST ^ c:\windows echo true 以查看解析器

      true

      但到目前为止,我还不知道为什么所有人都必须像上面那样工作。

      有趣的事,

      %^cmdcmdline%

      忽略所有 =

      已更新(2016-04-23),

      正如npcmaka所提到的,(IF DEFINED ^ username echo right)|more (IF EXIST ^ c:\windows echo right)|more echo pipe|if 123^ equ ====== 123 ====== echo %^cmdcmdline% 也是分隔符。

      CASE 1

      =

      输出,

      ,

      案例2

      echo pipe|if not defined^===neq === echo %^cmdcmdline%
      

      输出,

      C:\Windows\system32\cmd.exe  /S /D /c" if not defined=== neq echo %cmdcmdline%"
      

      echo pipe|if not defined^ === neq === echo %^cmdcmdline% 之间出现一个空格。

      CASE 3

      C:\Windows\system32\cmd.exe  /S /D /c" if not defined == = neq === echo %cmdcmdline%"
      

      输出,

      ===

      可以找到一些现象,可能知道如何解析......

      • echo pipe|if not defined^,,,neq ,,, echo %^cmdcmdline% 在所有 CASE 中被识别为变量。 (之前C:\Windows\system32\cmd.exe /S /D /c" if not defined,NEQ echo %cmdcmdline%" 会发生没有输出 CASE

      • CASE 2 中,分隔符neq中的set neq=blah似乎标识为比较,并且在后自动添加一个空格

      • 根据 CASE 2 中的规则,在 CASE 3 中,输入==为小写,输出===为大写。但是在 CASE 1&amp; 2 ,由于neq之前存在NEQ,此时==保持小写,但未标识为比较。

      所以它在解析器周期中有几个步骤。但是有一些添加或删除分隔符的错误。右吗

      CASE 4

      下一个代码似乎触发neq无限执行,

      neq

      它的运行方式与cmd

      相同

答案 3 :(得分:2)

我认为在管道中使用if语句的最简单的解决方法如下(外围的外围括号是必需的):

(if^ comparison_expression conditional_command_line)
(if^ comparison_expression (conditional_command_line) else other_conditional_command_line)

我使用notexistdefinedelse子句,所有可能的比较运算符(==,{{1}等所有关键字对其进行了测试},EQU等),用于管道的任一侧,以及NEQ和批处理文件。
此外,我还成功测试了cmd循环体内嵌入的if语句(在这种情况下,不再需要外括号)。