在R中执行Perl - 使用perlQuote/shQuote?

4

我想通过system命令在R中运行一些Perl代码:只需将从R中提供的字符串分配给变量并输出它。(system调用在/bin/sh中执行)

echo <- function (string) {
    cmd <- paste(shQuote(Sys.which('perl')),
                 '-e',
                 shQuote(sprintf("$str=%s; print $str", shQuote(string))))
    message(cmd)
    system(cmd)
}
# all fine:
# echo('hello world!')
# echo("'")
# echo('"')
# echo('foo\nbar')

然而,如果我尝试使用echo输出反斜杠(或以反斜杠结尾的任何字符串),就会出现错误:
> echo('\\')
'/usr/bin/perl' -e "\$str='\\'; print \$str"
Can't find string terminator "'" anywhere before EOF at -e line 1.

(注意:在$前面加上反斜杠是正确的,因为这样可以保护/bin/sh不会将$str视为shell变量。)
错误的原因是Perl将最后一个\'解释为$str内嵌的引号,而不是转义的反斜杠。实际上,要让perl回显反斜杠,我需要这样做。
> echo('\\\\')
'/usr/bin/perl' -e "\$str='\\\\'; print \$str"
\ # <-- prints this

也就是说,在Perl中,我需要转义我的反斜杠(除了在R/bash中我已经转义了它们)。 如何确保在echo中用户输入的字符串正常输出?即只需要在R级别进行转义? 也就是说,是否有类似于shQuoteperlQuote函数?我应该在echo函数中手动转义所有反斜杠吗?还有其他需要进行转义的字符吗?

我正在尝试为R创建一个"cowsay"软件包,以便与"fortunes"软件包结合使用,因此这个问题是有好处的! ;) - mathematical.coffee
2个回答

6

不要生成代码,这很难。相反,将参数作为参数传递:

echo <- function (string) {
    cmd <- paste(shQuote(Sys.which('perl')),
                 '-e', shQuote('my ($str) = @ARGV; print $str;'),
                 shQuote(string))
    message(cmd)
    system(cmd)
}

您也可以使用环境变量。

我以前从未使用过或甚至看到R代码,所以请原谅任何语法错误。


3
以下看起来可以工作。 在 Perl 中,我使用 q// 而不是引号,以避免与 shell 引号发生问题。
perlQuote <- function(string) {
  escaped_string <- gsub("\\\\", "\\\\\\\\", string)
  escaped_string <- gsub("/", "\\/", escaped_string)
  paste("q/", escaped_string, "/", sep="")
}
echo <- function (string) {
    cmd <- paste(shQuote(Sys.which('perl')),
                 '-le',
                 shQuote(sprintf("$str=%s; print $str", perlQuote(string))))
    message(cmd)
    system(cmd)
}
echo(1)
echo("'"); echo("''"); echo("'\""); echo("'\"'")
echo('"'); echo('""'); echo('"\''); echo('"\'"'); 
echo("\\"); echo("\\\\")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接