4

を使用して R から Perl を実行しようとしていますsystem。単純に文字列 (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

エラーは、Perlが最後を、エスケープされたバックスラッシュではなく\'、埋め込まれた引用符として解釈しているためです。$str実際、perl にバックスラッシュをエコーさせるには、次のようにする必要があります。

> echo('\\\\')
'/usr/bin/perl' -e "\$str='\\\\'; print \$str"
\ # <-- prints this

つまり、Perlのバックスラッシュをエスケープする必要があります(R/bash でバックスラッシュをエスケープすることに加えて)。

echoユーザーが入力した文字列が印刷される文字列であることを確認するにはどうすればよいですか? つまり、必要なエスケープのレベルは R レベルだけですか?

つまり、に類似した何らかのperlQuote機能がありshQuoteますか? 関数内のすべてのバックスラッシュを手動でエスケープする必要がありechoますか? 与えられたエスケープする必要がある他の文字はありますか?

4

2 に答える 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 コードを使ったことも見たこともないので、構文エラーはご容赦ください。)

于 2013-05-19T09:39:22.280 に答える
3

以下はうまくいくようです。Perl ではq//、シェルの引用符の問題を回避するために引用符の代わりに使用します。

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("\\\\")
于 2013-05-19T08:46:36.053 に答える