【问题标题】:Unix piping in system() does not work in Rsystem() 中的 Unix 管道在 R 中不起作用
【发布时间】:2021-10-28 04:03:33
【问题描述】:

我正在使用 system() 命令在 R 中运行 Bash 命令,但每次我尝试将一个命令的结果通过管道传递到下一个命令(使用“|”)时,都会出现一些错误。

例如: system('grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p | awk -F "\t" '{print $2}'') 返回错误:Error: unexpected '{' in "system('grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p | awk -F "\t" '{",如果我尝试删除 awk -F "\t" '{print $2}' 以便留下 system('grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p'),我会得到以下信息:

/usr/bin/grep: 2-: No such file or directory

[1] 2

我必须继续删除它的一部分,直到我只剩下system('grep ^SN bam_stats.txt'),也就是没有留下任何管道,它才能工作。

这是我从中提取信息的文件“bam_stats.txt”中的一个示例:

SN  filtered sequences: 0
SN  sequences:  137710356
SN  is sorted:  1
SN  1st fragments:  68855178
SN  last fragments: 68855178
SN  reads mapped:   137642653
SN  reads mapped and paired:    137602018   # paired-end technology bit set + both mates mapped
SN  reads unmapped: 67703
SN  percentage of properly paired reads (%):    99.8

谁能告诉我为什么管道不工作?抱歉,如果这是一个愚蠢的问题。如果我应该提供更多信息,请告诉我。

提前谢谢你。

【问题讨论】:

  • R 中的system('echo hello | cat') 是否在标准输出上发出hellohello | cat?如果是前者,则管道受到尊重。
  • ...stat.ethz.ch/R-manual/R-devel/library/base/html/system.html 确实明确记录了system() 应该在 UNIXy 系统上的 R 中使用 /bin/sh,所以我们不需要担心 R 是否有一个名为 @987654336 的函数@ 这实际上并没有启动一个 shell。
  • 现在,您的 original 错误更有意义 - 这是因为您试图将文字单引号放在单引号字符串中(所以为什么 awk 没有't work 是有道理的;如何在字符串中转义单引号是一个非常特定于语言的事情,你需要知道 R 的人来回答它)。
  • 也就是说,system() 不使用 bash,它使用 sh。这个问题应该标记为sh,而不是bash。它们是两个不同的 shell,虽然 bash 主要是 POSIX sh 的超集,但这并不意味着它们完全兼容。
  • @G5W,是的,我指出了这一点above。这个问题并不奇怪。另一方面,system('grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p') 的失败令人惊讶。

标签: r linux awk sh


【解决方案1】:

我不知道 R,但 system() 的 IF Rs 实现只是将它的参数传递给 shell,然后就标准 Unix 引用而言,您的示例

system('grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p | awk -F "\t" '{print $2}'')

在引号内包含 2 个字符串,中间包含一个在引号外的字符串:

  • 内部:grep ^SN bam_stats.txt | cut -f 2- | sed -n 8p | awk -F "\t"
  • 外部:{print $2}
  • 内部:<a null string>

因为'{print $2}' 周围中间的两个引号会结束第一个带引号的字符串,然后再开始第二个带引号的字符串。

如果您仍然使用 awk,则不需要 sed、grep 或 cut,尽管如此,请尝试以下操作:

system('awk -F"\t" "/^SN/ && (++cnt==8){print \$3}" bam_stats.txt')

【讨论】:

  • 看起来system("awk -F'\t' '/^SN/ && (++cnt==8) {print $3}' bam_stats.txt") 也应该可以工作,这样可以避免$ 的额外转义。
  • @chepner true,但如果R 允许在其system() args 周围使用双引号,则为idk。例如,Awk 允许 system("foo") 但不允许 system('foo') ,并且 OP 显示 R 允许 system('foo') 所以我只是将其作为 idk 使用,无论是否允许 system("foo")
  • tutorialspoint.com/r/r_strings.htm 至少建议您可以使用单引号或双引号来定义字符串。奇怪的是,在字符串中包含引号的 only 方法似乎是使用另一个。它没有提到任何类型的反斜杠转义。 (我所知道的关于 R 的几乎所有内容都在此评论部分中,所以请对我所说的一切持保留态度。)
  • 我想知道类似的事情,但没有进一步挖掘。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2017-05-28
  • 1970-01-01
  • 2021-11-25
  • 2018-01-25
  • 2017-07-02
  • 1970-01-01
相关资源
最近更新 更多