在Perl中使用globs替换TCL脚本中的一行程序
我想在TCL脚本中运行一个Perl one liner,如下所示:在Perl中使用globs替换TCL脚本中的一行程序,tcl,Tcl,我想在TCL脚本中运行一个Perl one liner,如下所示: exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} testFile; 这个很好用。但是,如果我想修改以下所有文件: exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} *; 它向我提供了错误消息: Can't open '*': No such file or directory. while executing exe
exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} testFile;
这个很好用。但是,如果我想修改以下所有文件:
exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} *;
它向我提供了错误消息:
Can't open '*': No such file or directory.
while executing
exec perl -i -pe {s/SUBSTRING/REPLACING_STRING/g} *;
我尝试支撑“*”,但没有解决问题。请求帮助 假设当前工作目录中存在文件
a
、b
和c
,在shell中执行echo*
,打印a b c
。这是因为shell命令计算器在找到通配符表达式的零个或多个文件名列表中识别通配符和拼接
Tcl的命令计算器不识别通配符,但将通配符未替换地传递给调用的命令。如果该命令可以与通配符一起使用,它将这样做。exec
命令没有,这意味着它将按原样将通配符表达式传递给由命令字符串命名的shell命令
通过测试,我们得到
% exec echo *
*
因为我们要求shell执行的只是
echo *
如果希望将通配符表达式扩展为文件名列表,则需要显式调用glob
命令:
% exec echo [glob *]
"a b c"
这仍然不太正确,因为列表没有自动拼接到命令字符串中:相反,shell得到了
echo {a b c}
(注意:我在Windows上假装echo
,实际输出可能不同。)
要扩展和拼接文件名列表,我们需要:
% exec echo {*}[glob *]
a b c
前缀{*}
告诉Tcl命令计算器替换以下参数,就好像它产生的单词是原始命令行中的参数一样
echo a b c
这个例子的解释比我在这里给出的更为简洁,它位于exec
的文档中:
如果您正在转换涉及shell全局绑定的调用,您应该记住,默认情况下Tcl不会处理全局绑定或将内容扩展为多个参数。您应该这样编写:
附言: 如果已加载
fileutil
包:
package require fileutil
这也可以在Tcl中写成一行程序:
foreach file [glob *] {::fileutil::updateInPlace $file {apply {str {regsub -all SUBSTRING $str REPLACING_STRING}}}}
或使用换行符和缩进以提高可读性:
foreach file [glob *] {
::fileutil::updateInPlace $file {
apply {str {
regsub -all SUBSTRING $str REPLACING_STRING
}}
}
}
文档:、包、、假设当前工作目录中存在文件
a
、b
和c
,在shell打印a b c
中执行echo*
。这是因为shell命令计算器在找到通配符表达式的零个或多个文件名列表中识别通配符和拼接
Tcl的命令计算器不识别通配符,但将通配符未替换地传递给调用的命令。如果该命令可以与通配符一起使用,它将这样做。exec
命令没有,这意味着它将按原样将通配符表达式传递给由命令字符串命名的shell命令
通过测试,我们得到
% exec echo *
*
因为我们要求shell执行的只是
echo *
如果希望将通配符表达式扩展为文件名列表,则需要显式调用glob
命令:
% exec echo [glob *]
"a b c"
这仍然不太正确,因为列表没有自动拼接到命令字符串中:相反,shell得到了
echo {a b c}
(注意:我在Windows上假装echo
,实际输出可能不同。)
要扩展和拼接文件名列表,我们需要:
% exec echo {*}[glob *]
a b c
前缀{*}
告诉Tcl命令计算器替换以下参数,就好像它产生的单词是原始命令行中的参数一样
echo a b c
这个例子的解释比我在这里给出的更为简洁,它位于exec
的文档中:
如果您正在转换涉及shell全局绑定的调用,您应该记住,默认情况下Tcl不会处理全局绑定或将内容扩展为多个参数。您应该这样编写:
附言: 如果已加载
fileutil
包:
package require fileutil
这也可以在Tcl中写成一行程序:
foreach file [glob *] {::fileutil::updateInPlace $file {apply {str {regsub -all SUBSTRING $str REPLACING_STRING}}}}
或使用换行符和缩进以提高可读性:
foreach file [glob *] {
::fileutil::updateInPlace $file {
apply {str {
regsub -all SUBSTRING $str REPLACING_STRING
}}
}
}
文档:、包、、exec不展开通配符。如果您将*替换为
{*}[glob*]
,会发生什么?嗨,彼得,您的解决方案非常有效。非常感谢你。如果您能告诉我它是如何工作的,我将非常高兴。exec不扩展通配符。如果您将*替换为{*}[glob*]
,会发生什么?嗨,彼得,您的解决方案非常有效。非常感谢你。如果您能告诉我它是如何工作的,我会很高兴。Windows上有一个echo
(如果您使用auto\u execok
,因为它是一个shell内置),但这与您所说的要点无关。shell在扩展方面没有Tcl那么谨慎,这就是问题的根源。扩展地球仪是正确的答案。非常感谢彼得的详细解释。这肯定有很大帮助。再次感谢:)Windows上有一个echo
(如果您使用auto_execok
,因为它是一个shell内置),但这与您所说的要点无关。shell在扩展方面没有Tcl那么谨慎,这就是问题的根源。扩展地球仪是正确的答案。非常感谢彼得的详细解释。这肯定有很大帮助。再次感谢:)