使用进程替换从 R 中的 system() 调用 comm
Calling comm from system() in R with process substitution
出于效率原因,我想通过 system() 在 R 中调用 comm。我已经习惯了使用如下语法:
comm -13 <(hadoop fs -cat /path/to/file | gunzip | awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{if( ~ /^".*"$/ && ~ /^".*"$/) {print toupper(),toupper()} else if( ~ /^[^"]/ && ~ /^["]/) {print "\""toupper()"\"",toupper()} else if( ~ /^[^"]/ && ~ /^[^"]/) {print "\""toupper()"\"","\""toupper()"\""}}' | sort) <(awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{if( ~ /^".*"$/ && ~ /^".*"$/) {print toupper(),toupper()} else if( ~ /^[^"]/ && ~ /^["]/) {print "\""toupper()"\"",toupper()} else if( ~ /^[^"]/ && ~ /^[^"]/) {print "\""toupper()"\"","\""toupper()"\""}}' /path/to/file | sort)
但是当从系统中使用此语法时,如
system("comm -13 <(filea) <fileb)")
我遇到熟悉的错误:
sh: -c: line 0: syntax error near unexpected token `('
从上面可以清楚地看出 system() 使用的是 sh 而不是 bash,并且不支持进程替换。阅读其他文章后,我尝试使用
system("bash -c 'comm -13 <(hadoop fs -cat /path/to/file | gunzip | awk -vFPAT='([^,]*)|(\"[^\"]+\")' -vOFS=, '{if( ~ /^\".*\"$/ && ~ /^\".*\"$/) {print toupper(),toupper()} else if( ~ /^[^\"]/ && ~ /^[\"]/) {print \"\\"\"toupper()\"\\"\",toupper()} else if( ~ /^[^\"]/ && ~ /^[^\"]/) {print \"\\"\"toupper()\"\\"\",\"\\"\"toupper()\"\\"\"}}' | sort) <(awk -vFPAT='([^,]*)|(\"[^\"]+\")' -vOFS=, '{if( ~ /^\".*\"$/ && ~ /^\".*\"$/) {print toupper(),toupper()} else if( ~ /^[^\"]/ && ~ /^[\"]/) {print \"\\"\"toupper()\"\\"\",toupper()} else if( ~ /^[^\"]/ && ~ /^[^\"]/) {print \"\\"\"toupper()\"\\"\",\"\\"\"toupper()\"\\"\"}}' /path/to/file | sort)")
也就是说,根据需要转义双引号和反斜杠。但是,这个returns同样的错误:
sh: -c: line 0: syntax error near unexpected token `('
我猜这与在 system() 中双引号字符串中 bash -c 中的单引号转义有关。我对如何在 bash -c within system() 中的双引号字符串中管理单引号感到有点困惑。我应该如何应对所有这些转义?
为了解决这个问题,我只需要转义里面的所有东西:
bash -c "[within]"
使用bash的转义规则(https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html),以及within2中的所有内容:
system("[within2]")
使用 R 的转义规则。
最终结果是双重转义反斜杠和引号(bash 和 R),以及单一转义 $ (bash).
出于效率原因,我想通过 system() 在 R 中调用 comm。我已经习惯了使用如下语法:
comm -13 <(hadoop fs -cat /path/to/file | gunzip | awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{if( ~ /^".*"$/ && ~ /^".*"$/) {print toupper(),toupper()} else if( ~ /^[^"]/ && ~ /^["]/) {print "\""toupper()"\"",toupper()} else if( ~ /^[^"]/ && ~ /^[^"]/) {print "\""toupper()"\"","\""toupper()"\""}}' | sort) <(awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{if( ~ /^".*"$/ && ~ /^".*"$/) {print toupper(),toupper()} else if( ~ /^[^"]/ && ~ /^["]/) {print "\""toupper()"\"",toupper()} else if( ~ /^[^"]/ && ~ /^[^"]/) {print "\""toupper()"\"","\""toupper()"\""}}' /path/to/file | sort)
但是当从系统中使用此语法时,如
system("comm -13 <(filea) <fileb)")
我遇到熟悉的错误:
sh: -c: line 0: syntax error near unexpected token `('
从上面可以清楚地看出 system() 使用的是 sh 而不是 bash,并且不支持进程替换。阅读其他文章后,我尝试使用
system("bash -c 'comm -13 <(hadoop fs -cat /path/to/file | gunzip | awk -vFPAT='([^,]*)|(\"[^\"]+\")' -vOFS=, '{if( ~ /^\".*\"$/ && ~ /^\".*\"$/) {print toupper(),toupper()} else if( ~ /^[^\"]/ && ~ /^[\"]/) {print \"\\"\"toupper()\"\\"\",toupper()} else if( ~ /^[^\"]/ && ~ /^[^\"]/) {print \"\\"\"toupper()\"\\"\",\"\\"\"toupper()\"\\"\"}}' | sort) <(awk -vFPAT='([^,]*)|(\"[^\"]+\")' -vOFS=, '{if( ~ /^\".*\"$/ && ~ /^\".*\"$/) {print toupper(),toupper()} else if( ~ /^[^\"]/ && ~ /^[\"]/) {print \"\\"\"toupper()\"\\"\",toupper()} else if( ~ /^[^\"]/ && ~ /^[^\"]/) {print \"\\"\"toupper()\"\\"\",\"\\"\"toupper()\"\\"\"}}' /path/to/file | sort)")
也就是说,根据需要转义双引号和反斜杠。但是,这个returns同样的错误:
sh: -c: line 0: syntax error near unexpected token `('
我猜这与在 system() 中双引号字符串中 bash -c 中的单引号转义有关。我对如何在 bash -c within system() 中的双引号字符串中管理单引号感到有点困惑。我应该如何应对所有这些转义?
为了解决这个问题,我只需要转义里面的所有东西:
bash -c "[within]"
使用bash的转义规则(https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html),以及within2中的所有内容:
system("[within2]")
使用 R 的转义规则。
最终结果是双重转义反斜杠和引号(bash 和 R),以及单一转义 $ (bash).