【问题标题】:How to pass a single quote (') into a batch script?如何将单引号 (') 传递到批处理脚本中?
【发布时间】:2018-03-16 20:08:36
【问题描述】:

您好,感谢您的帮助。

我在转义 Windows 批处理脚本中的单引号字符 (') 时遇到了困难。我试过 ^'、\'、'''、'\'' 等等。在线搜索也没有解决它。我被难住了。

此脚本使用 cgywin64 gawk 格式化文件夹列表:

@echo off
du -sk ./*  | sort -nr | head -40 | gawk '{printf("%%^'14d kB %%s %%s %%s %%s %%s %%s %%s %%s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9)}'

运行时出现以下错误:

gawk: cmd. line:1: {printf("%^14d
gawk: cmd. line:1:         ^ unterminated string
gawk: cmd. line:1: {printf("%^14d
gawk: cmd. line:1:         ^ syntax error

不进行任何字符转义,gawk 命令看起来像:

gawk '{printf("%'14d kB %s %s %s %s %s %s %s %s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9)}'

开头的格式字符串 (%'14d) 告诉 gawk 在打印整数时使用逗号(“123456789”打印为“123,456,789”)。 这个字符串有一个单引号('),我不知道如何正确地传递给批处理脚本。

那么如何将单引号 (') 传递到批处理脚本中?

任何帮助表示赞赏。

【问题讨论】:

  • 试试命令行:du -sk ./* | sort -nr | head -40 | gawk "{printf(\x22%%'14d kB %%s %%s %%s %%s %%s %%s %%s %%s\n\x22, $1, $2, $3, $4, $5, $6, $7, $8, $9)}"。我没有安装 gawk。有关为什么在参数字符串周围使用" 并在带有\x22 的字符串内引用" 的详细信息,请参阅gawk command in CMD with && operator not working 上的答案。
  • 单引号不应该是一个问题,但是你的双引号和百分比字符是。您可能会发现官方的user guide 建议值得一读。
  • Single quotes have no special meaning in Windows batch,所以'{printf("%%^'14d kB %%s %%s %%s %%s %%s %%s %%s %%s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9)}' 不是您预期的单个参数。您必须始终使用"。或者只是更改为可以使用单引号的powershell
  • 莫菲,谢谢你们的cmets。不幸的是,添加 \x22 失败,在 \x22 处出现语法错误。但是下面的 Compos 回答有效。再次感谢大家的帮助!

标签: windows batch-file awk gawk


【解决方案1】:

以下建议未经测试,目前仅基于我有限的理解。

gAwk 使用单引号在 POSIX 兼容的 Bourne 样式 shell 中引用,cmd.exe 不是其中之一。

在 cmd.exe 中,用于引用的单引号 ' 需要替换为双引号 "

不用于引用的单引号 %'14d 不需要 gAwk 特别注意,因为双引号中的字符受到保护。

在cmd.exe中单引号是没有问题的,所以这个字符可以保持不变。

所以在 cmd.exe 中你需要将周围的单引号 '{}' 替换为双引号 "{}"

然后您必须转义内部双引号以防止 cmd.exe 过早关闭开头的 "{

在 cmd.exe 中,双引号通常通过在其前面加上反斜杠 \" 进行转义。

因此,您在 cmd.exe 中的命令将如下所示:

du -sk ./*  | sort -nr | head -40 | gawk "{printf(\"%'14d kB %s %s %s %s %s %s %s %s\n\", $1, $2, $3, $4, $5, $6, $7, $8, $9)}"

以上建议适用于 cmd.exe;但是,当从批处理文件运行时,会有一个额外的问题。

所有百分比字符都需要加倍! % 变为 %%

鉴于以上所有情况,请记住这是完全未经测试的,您在批处理文件中的命令将是:

du -sk ./*  | sort -nr | head -40 | gawk "{printf(\"%%'14d kB %%s %%s %%s %%s %%s %%s %%s %%s\n\", $1, $2, $3, $4, $5, $6, $7, $8, $9)}"

【讨论】:

  • 我不清楚实际序列%'14d,我不确定我是否见过这种符号。我希望%14d 将输出/填充到 14 位数字,我注意到 %'d%'i(可互换的数字和整数) 用于根据数千个分组字符输出到任何系统设置的语言环境信息。因此,我的假设是,这个序列应该输出一个 14 位数字,带有千位分隔符,(不一定是逗号或任何逗号)
  • Compo,你观察到 %'14d “应该输出一个 14 位数字,带有千位千位分隔符,(不一定是逗号或任何逗号)!”也是正确的(正如我刚刚发现的那样)。我现在必须弄清楚如何设置 cygwin 本地信息以在数字中使用逗号(我正在移植一个使用默认本地信息的 linux 脚本。看起来我必须设置 cygwin 本地信息。)再次,谢谢寻求帮助!
  • 如果命令运行没有错误,只是系统中没有分隔符且没有设置分隔符,您仍应将答案标记为已接受,因为它可以按预期有效地运行命令。
  • 很好和详细的解释,我很感激。不幸的是,有些情况不符合这种解释。当我们使用这个时该怎么做:for /f "tokens=*" %%a in ('echo select 'TEST' from dual; ^| sqlplus -s user/password) do echo %%a`。我们肯定需要转义单引号,但我不知道如何......有什么想法吗?
  • @menssana,这与原始问题或我的答案无关,因为您的问题与使用 for-loop 有关。如果您打开命令提示符窗口并输入for /?,您应该在FOR /F 下的部分中注意到usebackq 选项,因此请尝试使用它。例如For /F "UseBackQ Tokens=*" %%I In (`Echo select 'TEST' from dual; ^| SQLPlus -s user/password`)Do Echo %%I.
猜你喜欢
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
  • 2011-11-05
  • 2023-01-23
相关资源
最近更新 更多