【问题标题】:How to echo special characters in batch file?如何在批处理文件中回显特殊字符?
【发布时间】:2016-02-25 08:32:38
【问题描述】:

我想将下面的查询传递给sqlplus 命令。

select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13) || CHR(10)||'Status:  ' || a1.STORAGE_STATUS ||  CHR(13) || CHR(10)|| 'Distribution ID:  ' || a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;

当我使用插入符号 ^ 在屏幕上回显它时,它运行良好。

echo select 'Version ID:   ' ^|^| a1.BACKUP_VERSION  ^|^| CHR(13) ^|^| CHR(10)^|^|'Status:  ' ^|^| a1.STORAGE_STATUS ^|^|  CHR(13) ^|^| CHR(10)^|^| 'Distribution ID:  ' ^|^| a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;

它显示正确的查询字符串。但是当我在我的批处理文件中使用它时它不起作用。这是我要运行的代码:

@ECHO OFF
echo Connecting to Database...
echo +++++++++++++++++++++++++
(
echo user/pass@instance
echo select 'Version ID:   ' ^|^| a1.BACKUP_VERSION  ^|^| CHR(13) ^|^| CHR(10)^|^|'Status:  ' ^|^| a1.STORAGE_STATUS ^|^|  CHR(13) ^|^| CHR(10)^|^| 'Distribution ID:  ' ^|^| a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;
)| sqlplus -s
echo +++++++++++++++++++++++++

它只显示这个:

Connecting to Database...
+++++++++++++++++++++++++
user/pass@instance
select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13
+++++++++++++++++++++++++

它没有将查询传递给sqlplus 命令,怎么办?

【问题讨论】:

    标签: sql oracle batch-file escaping


    【解决方案1】:

    您需要转义右括号,例如^)。您的echo 命令位于一对括号() 之间的代码块内;任何未转义的右括号都被解释为该块的结尾。所以固定的代码看起来像:

    echo select 'Version ID:   ' ^|^| a1.BACKUP_VERSION  ^|^| CHR^(13^) ^|^| CHR^(10^)^|^|'Status:  ' ^|^| a1.STORAGE_STATUS ^|^|  CHR^(13^) ^|^| CHR^(10^)^|^| 'Distribution ID:  ' ^|^| a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;
    

    为了代码的易读性,我也跳过了左括号^(,尽管这不是绝对必要的;所以很清楚哪些括号是功能性的,哪些是装饰性的。

    在批处理脚本中,您使用管道| 将输出传递给sqlplus 命令;这需要像这样进行双重转义:

    @echo off
    echo Connecting to Database...
    echo +++++++++++++++++++++++++
    (
    echo user/pass@instance
    echo select 'Version ID:   ' ^^^|^^^| a1.BACKUP_VERSION  ^^^|^^^| CHR^^^(13^^^) ^^^|^^^| CHR^^^(10^^^)^^^|^^^|'Status:  ' ^^^|^^^| a1.STORAGE_STATUS ^^^|^^^|  CHR^^^(13^^^) ^^^|^^^| CHR^^^(10^^^)^^^|^^^| 'Distribution ID:  ' ^^^|^^^| a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;
    ) | sqlplus -s
    echo +++++++++++++++++++++++++
    

    这是因为管道为| 的每一侧创建了新的命令提示符实例,代码部分在此处执行;所以特殊字符需要从运行批处理文件的主命令提示符实例中隐藏,并形成由管道进程创建的实例。


    另一种选择是将要输出的字符串放在一对双引号"" 之间(假设字符串本身不包含此类字符)。但是,不能使用像 echo "..." 这样的命令行,因为 "" 包含在输出中,这是我们不想要的。

    一个技巧是使用set /P,它旨在提示用户输入环境变量的值。这里不需要变量(#),只需要提示文字:

    set /P "#=select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13) || CHR(10)||'Status:  ' || a1.STORAGE_STATUS ||  CHR(13) || CHR(10)|| 'Distribution ID:  ' || a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;"
    

    为避免此命令等待用户输入,我们通过管道将echo 插入其中(只有一个_ 字符):

    echo _| set /P "#=select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13) || CHR(10)||'Status:  ' || a1.STORAGE_STATUS ||  CHR(13) || CHR(10)|| 'Distribution ID:  ' || a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;"
    

    最后,让我们在批处理脚本中使用所有这些:

    @echo off
    echo Connecting to Database...
    echo +++++++++++++++++++++++++
    (
    echo user/pass@instance
    echo _| set /P "#=select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13) || CHR(10)||'Status:  ' || a1.STORAGE_STATUS ||  CHR(13) || CHR(10)|| 'Distribution ID:  ' || a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;"
    echo/
    ) | sqlplus -s
    echo +++++++++++++++++++++++++
    

    echo相反,set /P显示的文本不会被最后的换行符终止;这就是我插入echo/ 行的原因,它输出一个换行符。

    【讨论】:

    • 它可以工作,但只有没有管道|,我忘记了,抱歉;查看我的编辑...
    • 我刚刚添加了一个使用set /P""的替代方法;这样就避免了(双重)转义的需要......
    【解决方案2】:

    你可以使用插入符号,但是当你想用管道传递它时,你需要将每个特殊字符转义两次,并且加上引号,整个事情都很讨厌。

    您可以使用延迟扩展来避免这种情况

    set "sql=select 'Version ID:   ' || a1.BACKUP_VERSION  || CHR(13) || CHR(10)||'Status:  ' || a1.STORAGE_STATUS ||  CHR(13) || CHR(10)|| 'Distribution ID:  ' || a1.DISTRIBUTION_ID FROM epc1_distrib_version a1;"
    
    (
      echo user/pass@instance
      cmd /v:on /c "echo ^!sql^!"
    ) | sqlplus -s
    

    顺便说一句。要测试您的转义,您可以将 sqlplus 替换为 more 以查看您真正回应的内容

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 2011-11-10
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多