我曾经遇到过同样的问题,我开发的解决方法是在将输入命令行参数传递给 optparse
解析器之前调整它们,通过使用另一种分隔符(例如“管道”字符)将空格分隔的输入文件名连接在一起,这不太可能作为文件名的一部分使用。
然后,在最后再次反转调整,通过使用 str_split()
删除分隔符。
以下是一些示例代码:
library(optparse)
library(stringr)
insert_delimiter <- function(rawarg) {
flagloc <- c(0, which(str_detect(rawarg, '^-')))
n <- length(flagloc)
flagloc[n+1] <- length(rawarg) + 1
concatarg <- c()
ii <- 1
for(ij in seq(1,length(flagloc)-1)) {
step <- flagloc[ij+1]-flagloc[ij]
if (step == 1) {
if (ij != 1) {
concatarg[ii] <- rawarg[flagloc[ij]]
ii <- ii + 1
}
}
else if (step == 2) {
concatarg[ii] <- rawarg[flagloc[ij]]
concatarg[ii+1] <- rawarg[flagloc[ij]+1]
ii <- ii + 2
}
else if (step > 2) {
concatarg[ii] <- rawarg[flagloc[ij]]
concatarg[ii+1] <- paste0(rawarg[(flagloc[ij]+1):(flagloc[ij+1]-1)],
collapse='|')
ii <- ii + 2
}
}
return(concatarg)
}
remove_delimiter <- function(rawopt) {
outopt <- list()
for(nm in names(rawopt)) {
if (typeof(rawopt[[nm]]) == "character") {
outopt[[nm]] <- unlist(str_split(rawopt[[nm]], '\\|'))
} else {
outopt[[nm]] <- rawopt[[nm]]
}
}
return(outopt)
}
option_list <- list(
make_option(c('-i', '--inputfiles'), type='character', dest='fnames',
help='Space separated list of file names', metavar='INPUTFILES'),
make_option(c('-p', '--printvar'), type='character', dest='pvar',
help='Valid options are "yes" or "no"',
metavar='PRINTVAR'),
make_option(c('-s', '--size'), type='integer', dest='sz',
help='Integer size value',
metavar='SIZE')
)
opt <- remove_delimiter(parse_args(OptionParser(option_list=option_list),
args=insert_delimiter(commandArgs(trailingOnly = TRUE))))
print(opt)
假设上面的文件名为
fix_optparse.R
,以下是输出结果:
> chmod +x fix_optparse.R
> ./fix_optparse.R --help
Usage: ./fix_optparse.R [options]
Options:
-i INPUTFILES, --inputfiles=INPUTFILES
Space separated list of file names
-p PRINTVAR, --printvar=PRINTVAR
Valid options are "yes" or "no"
-s SIZE, --size=SIZE
Integer size value
-h, --help
Show this help message and exit
> ./fix_optparse.R --inputfiles fileA.txt fileB.txt fileC.txt --printvar yes --size 10
$fnames
[1] "fileA.txt" "fileB.txt" "fileC.txt"
$pvar
[1] "yes"
$sz
[1] 10
$help
[1] FALSE
>
这种方法的一个小限制是,如果任何其他参数有可能接受“管道”字符作为有效输入,则这些参数将无法正确处理。但是我认为您可能可以开发一个稍微复杂一些的版本来正确处理该情况。这个简单版本大多数时候都能工作,并且说明了一般思路。