寻找解析类Shell风格key=value文件的成熟R库函数
解析类Shell风格key=value文件的成熟库方案
首先看你给出的key=value文件内容:
a=foo b="foo bar" c="foo \"bar\"" d="foo 'bar'"
你用常规方法解析后得到的结果保留了引号和转义符:
txt <- readLines("dat") spl <- strsplit(txt, "=") vec <- setNames(sapply(spl, `[`, 2), sapply(spl, `[`, 1))
输出结果:
a b c d "foo" "\"foo bar\"" "\"foo \\\"bar\\\"\"" "\"foo \\\'bar\\'\""
你自定义的prs函数通过eval(parse())处理后得到了正确结果,但这种方式存在代码注入风险,而且可以用更成熟的库函数替代,无需依赖commandArgs():
推荐工具1:shellwords包
shellwords包专门实现了类Shell的字符串分词逻辑,直接处理字符串即可:
library(shellwords) parse_shell_val <- function(el) { # 判断是否是引号包裹的字符串 if (substr(el, 1, 1) %in% c("\"", "'")) { # 拆分后合并,还原原始内容 paste(shell_split(el), collapse = " ") } else { el } } # 应用到你的向量上 sapply(vec, parse_shell_val)
执行后得到正确结果:
a b c d "foo" "foo bar" "foo \"bar\"" "foo 'bar'"
推荐工具2:processx包
processx是常用的系统进程交互库,其中split_command()函数可以解析类Shell风格的命令行字符串:
library(processx) parse_with_processx <- function(el) { # 构造虚拟命令行,将目标字符串作为参数 parsed <- split_command(paste0("dummy ", el)) # 移除虚拟命令名,合并剩余部分得到解析后的值 paste(parsed[-1], collapse = " ") } # 应用到向量 sapply(vec, parse_with_processx)
这个方法同样能正确处理转义引号和空格分隔的内容,且库维护活跃,稳定性强。
这两个库的实现都比自定义的eval(parse())更安全,避免了潜在的代码注入风险,同时完全满足你不需要依赖commandArgs()的需求。
内容的提问来源于stack exchange,提问作者antonio
相关产品推荐
相关产品推荐

