告诉批处理脚本不接受包含引号的变量

时间:2017-02-01 05:00:13

标签: windows batch-file variables

我试图让批处理脚本不接受引号作为可接受的变量。

例如:

exa"mple

所以我基本上,无论变量是什么,如果它甚至有一个引号(是的,甚至在一个单词里面,如:

from pyspark import SparkContext
from pyspark.sql import SQLContext
from pyspark.sql.types import *


if __name__ == "__main__":
    sc = SparkContext(appName="CSV2Parquet")
    sqlContext = SQLContext(sc)

    schema = StructType([
            StructField("id", LongType(), True),
            StructField("domain", StringType(), True)
           ])

    rdd = sc.textFile("hdfs://10.11.21.33:8020/users2.txt").map(lambda line: line.split(","))
    df = sqlContext.createDataFrame(rdd, schema)
    df.write.parquet('hdfs://10.11.21.33:8020/input-parquet-spark20')

它不会接受它并提示用户输入其他内容。

谢谢

2 个答案:

答案 0 :(得分:2)

以下代码可用于检查用户输入:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

:setmyvar
set "myvariable=""
set /P "myvariable=Please enter: "
set "TestVar=!myvariable:"=!"

if not defined TestVar goto setmyvar

if not "!TestVar!" == "!myvariable!" (
    echo/
    echo Variable cannot contain quotation marks.
    echo/
    pause
    echo/
    goto setmyvar
)

echo Success^^!
rem Other commands.
endlocal

在提示用户之前,使用双引号定义环境变量myvariable。如果用户只是点击 RETURN ENTER ,环境变量myvariable将保持其当前值(或者如果之前未定义,则仍未定义)。

在用户提示后,使用环境变量TestVar的值定义了新的环境变量myvariable,但删除了所有双引号。

现在有三种可能性:

  1. TestVar现在根本没有定义,因为用户没有输入任何内容或只是双引号。
  2. TestVarmyvariable不同,因为myvariable包含其他字符,还有一个或多个双引号。
  3. TestVar等于myvariable,因为用户输入的字符串不包含任何双引号。
  4. 对于不相等的环境变量的比较,有必要使用delayed expansion,否则使用双引号的直接环境变量扩展%myvariable%将导致语法错误。

    在第一种情况下,只需再次提示用户。

    在第二种情况下,用户被告知要求输入不带引号的字符串,然后可以再次输入字符串,用户可以使用向上箭头来调用先前输入的字符串并编辑它

    在第三种情况下,批处理文件继续执行。

    要使用echo输出的文本中的感叹号必须使用两个插入符进行转义,因为仍然需要延迟扩展才能使剩余代码访问myvariable的值。在endlocal之后,除了使用以下命令行之外,环境变量myvariable不再存在:

    endlocal & set "myvariable=%myvariable%"
    

    在解析此命令行时,此行将在活动环境中由命令myvariable恢复的先前环境中定义endlocal,当前值为myvariable

    echo/只是以比echo.更安全的方式输出一个空白行。

    要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

    • echo /?
    • endlocal /?
    • goto /?
    • if /?
    • rem /?
    • set /?
    • setlocal /?

    有关setlocalendlocal阅读this answer的内容以及其中引用的其他两个答案的更多帮助。有关使用set "variable=value"的说明,请参阅Why is no string output with 'echo %var%' after using 'set var = text' on command line?

    上的答案

答案 1 :(得分:2)

与Mofi answer中使用的引用检测方法相同(如果删除引号后变量中的值不会更改,则变量不包含引号),代码逻辑已简化并延迟扩展仅在需要时启用。

@echo off
    setlocal enableextensions disabledelayedexpansion

:input
    set /p "userInput=? " || (
        echo Error - Empty input not allowed
        goto :input
    )

    setlocal enabledelayedexpansion
    if not !userInput!==!userInput:^"=! set "userInput="
    endlocal & if "%userInput%"=="" (
        echo Error - Invalid input - quotes not allowed
        goto :input
    )

    Echo Ok - Successful input

如果用户没有输入任何内容,则set /p命令失败,此失败由||条件运算符处理(如果前一个命令失败,则执行下一个命令),请求新输入。< / p>

处理可能包含特殊字符和不平衡引号的字符串可能会有问题,但延迟扩展允许我们在执行一些更有问题的解析器阶段后使用变量中的值。因此,启用了延迟扩展并使用字符串替换操作(不带引号替换引号),我们检查变量中的值与没有引号的相同值。如果他们不匹配,我们会清理变量。

之后,不需要延迟扩展并禁用。这样做,如果变量包含引号,我们将失去对变量所做的更改(干净),但是在执行之前解析行,使用常规变量引用(%var%)而不是延迟扩展引用(!var! )在开始执行行中的命令之前,将读取操作替换为变量中的值,因此,我们可以检索更改的值。如果变量为空,则它包含引号,我们应该请求一个新值。