在 R 中,如何通过 ssh 和 awk 进行读取

问题描述 投票:0回答:1

远程服务器上有很多文件,我想将其

fread
放入R中。 如果我在 R 中远程,我可以做

require(data.table)
f <- fread(cmd="awk '{print $0\"\t\"FILENAME}' path/to/myfile*.txt")

我得到了预期的输出,其中文件名作为附加列。

如果我在本地并且需要通过 ssh,我尝试过:

f <- fread(cmd='ssh user@remote awk \\"{print $0 FILENAME}\\" path/to/myfile*.txt')

但我只得到

f
中的文件名,但没有内容。我想我没有让
cmd=
字符串正确通过 ssh,我是否错误地转义了某些内容?我做错了什么?

r string ssh data.table
1个回答
0
投票

内容缺失是因为远程服务器中实际执行的命令是

awk "{print sh FILENAME}" path/to/myfile*.txt
,因为在执行
$0
之前,
"sh"
已被shell(由fread启动)替换为
ssh
。这可以通过

确认
data.table::fread(cmd='ssh user@remote awk -vsh=123 \\"{print $0 FILENAME}\\" path/to/myfile.txt')

它为您提供了一张

"123path/to/myfile.txt"
表。

要将正确的脚本命令传递给

awk
,你必须做很多转义,几种可能的解决方案是:

data.table::fread(cmd="ssh user@remote awk {print\\\\ \\\\\\$0\\\\,FILENAME} path/to/myfile*.txt")
# that's a lot of "\"'s

data.table::fread(cmd="ssh user@remote awk '{print\\ \\$0\\,FILENAME} path/to/myfile*.txt")
# A lot of characters still requires escaping, including ` `, `,`, `$` and `"`

data.table::fread(cmd="ssh user@remote awk \\''{print $0,FILENAME}'\\' path/to/myfile*.txt")
# now you can write awk scripts almost natively, only `\` and `"` require escaping.

要进行此类转义,首先,您需要在远程服务器中执行命令,例如,

awk '{print $0"\t"FILENAME}' path/to/myfile*.txt
# or without `'`
awk {print\ \$0\"\\t\"FILENAME} path/to/myfile*.txt
# if you use `,` in the script, either `{`, `}` or `,` should be escaped 
awk \{print\ \$0,FILENAME} path/to/myfile*.txt
  • awk
    将脚本参数作为一个参数,因此如果不加引号,
     
    应该被转义。
  • $0
    将被替换,除非它被
    '
    引用,或其
    $
    被转义。
  • A
    \
    将“按原样”保留其后面的字符,除非它被
    '
    引用。
  • {A,B}
    将展开(大括号展开),除非
    {
    ,
    }
    中的任何一个被转义。

那么你应该在本地 shell 中转义该命令:

# keep the statement using `''` quotation
ssh user@remote awk \''{print $0"\t"FILENAME}'\' path/to/myfile*.txt # the `'` can be escape using `\`
ssh user@remote awk '{print\ \$0\"\\t\"FILENAME}' path/to/myfile*.txt
ssh user@remote awk '\{print\ \$0,FILENAME}' path/to/myfile*.txt

# otherwise, escape anything that can break an argument or be substituted by the local shell
ssh user@remote awk \'{print\ \$0\"\\t\"FILENAME}\' path/to/myfile*.txt
ssh user@remote awk {print\\ \\\$0\\\"\\\\t\\\"FILENAME} path/to/myfile*.txt
ssh user@remote awk \\\{print\\\ \\\$0,FILENAME} path/to/myfile*.txt

最后你转义了 R 字符串中的所有

\
和引号:

cmd="ssh user@remote awk \\''{print $0\"\\t\"FILENAME}'\\' path/to/myfile*.txt"

# really A LOT of `\`'s
cmd='ssh user@remote awk {print\\\\ \\\\\\$0\\\\\\"\\\\\\\\t\\\\\\"FILENAME} path/to/myfile*.txt'

现在您可以享受从远程服务器读取文件的乐趣,而无需创建任何中间文件!

© www.soinside.com 2019 - 2024. All rights reserved.