如何使用 msys (mingw32) 在 tcl 中转义字符串
Posted
技术标签:
【中文标题】如何使用 msys (mingw32) 在 tcl 中转义字符串【英文标题】:how to escape string in tcl with msys (mingw32) 【发布时间】:2014-01-01 19:40:36 【问题描述】:我试图让 tcl 转义 MSys/MinGW 下的字符串(来自 mingw.org)。 tcl 的版本来自 mingw.org(通过 mingw-get,截至 2013 年 12 月)。
在 bash 中,我可以对字符串执行此操作(简化示例):
printf %q 'a \b $2'
printf '%q' "a \ b \' \" \$2"
返回:
a\ \\b\ \$2
a\ \\b\ \\\'\ \"\ \$2
分别。
但是,如果字符串存储在变量中或从文件中读取,我无法使第二个示例在 tclsh 或 tcl 中工作。我尝试过的事情是:
% set s a \b ' " $2
% printf %q $s
/usr/bin/printf: %q: invalid conversion specification
child process exited abnormally
(我猜这是由于 msys printf.exe 不能很好地与 tclsh 配合造成的)。
%exec bash -c "printf %q $s"
/usr/bin/bash: -c: line 0: unexpected EOF while looking for matching `''
/usr/bin/bash: -c: line 1: syntax error: unexpected end of file
(这里,考虑到$s 中的单引号和双引号,我什至不知道如何正确引用$s)。知道如何完成这项工作吗?
谢谢
-- 更新--
@Donal Fellows 的答案适用于原始字符串。我有:
% exec bash -c printf %q "$0" $s
a\ \\b\ \'\ \"\ \ \$2
但它不适用于我第一次遇到的测试字符串。如果字符串中有结束行,答案似乎不起作用。
% set s1 a \b ' "
$2
% exec bash -c printf %q "$0" $s1
我期待的是这样的:
a\ \\b\ \'\ \"\ \n\ \$2
奇怪的是,上面的exec
返回:
$'a \\b \' " \n $2 '
这似乎是一团糟。有一个不需要的前导 $'
,并且双引号 "
没有正确转义。并且空白 不会像以前一样转义到
\
。有什么想法吗?
-- 更新 2--
正如@Donal Fellows 所解释的,上面的字符串$'a \\b \' " \n $2 '
是用于引用的bash 特殊形式。我的最后一个问题是如何在 tcl 中转义/使用这种特殊形式。例如:
set s ls
echo '"'
set ss [exec bash -c printf %q "$0" $s]
返回:
$' ls\n echo \'"\' '
我可以在 bash (msys/mingw) 中使用这个特殊形式的字符串:
eval $' ls\n echo \'"\' '
执行两行命令(ls 和 echo '"'),并返回,例如:
a.txt
"
但是,我不知道如何在 tclsh 中完成这项工作。
% exec bash -c eval $ss
什么都不返回。我尝试了其他一些组合。没有工作。关于如何转义/取消转义这个的任何指示?
谢谢
【问题讨论】:
【参考方案1】:printf
既是 msys 中的命令 也是 bash 中的内置命令。 只有内置的 bash 支持%q
。 这意味着从 Tcl 调用它比平常更棘手,因为您还必须协商 bash 的引用。这需要这种相当笨拙的结构:
exec bash -c printf %q "$0" $s
大括号内的部分是shell语法,其余部分是Tcl语法;通过这样做,它将与(正确地使用 shell-quote)any 输入一起工作。请注意,Tcl 的大括号就像 bourne shell 单引号一样工作,除了它们是可嵌套的。
如果你想在 bash 中使用特殊形式,你可以将它替换到 bash 脚本中在 Tcl 中:
set quoted [exec bash -c printf %q "$0" $s]
exec bash -c "eval $quoted"
(这没关系。printf %q
正是为了使这项工作正常进行引用;这就是它的目的。)
如果您有一个复杂的脚本,将在您不想这样做的地方使用引用的片段,您最终会再次将其作为参数传递并在必要时使用另一个 eval
:
exec bash -c
# You can get *really* complicated in here!
eval eval "$0"
$quoted
但如果这种情况继续发生,可能是时候考虑您的方法是否正确……
【讨论】:
我不知道为什么会有一个名称相同但行为不一致的单独命令。唉,Unix 有时就是这样。 非常感谢您的回答。它在原始测试字符串上效果很好,但如果字符串中有结束行字符,它就会崩溃。请查看更新。 @TingL 这实际上是正确的; bash 有一个$'…'
的特殊形式,它的产生是合法的 bash 的printf %q
。
虽然我以前从未注意到过该表格,但它确实记录在手册页中。显然,it's part of SUS issue 7.
非常感谢您提供的详细信息。这真的很有帮助。关于特殊表格的使用,我还有最后一个问题。请查看更新。以上是关于如何使用 msys (mingw32) 在 tcl 中转义字符串的主要内容,如果未能解决你的问题,请参考以下文章