如何使用正则表达式进行 scp

如何使用正则表达式进行 scp

我正在尝试复制 ksh 中不以字母“a”开头的所有文件。

从源机器复制到目标机器是工作正常:

scp -p !(a*) user@machine:/path/directory/.

但是,如果我在目标服务器上并且想要从源服务器复制,则会失败:

scp -p user@machine:/path/!(a*) .

有任何想法吗?

答案1

我同意冯布兰德的观点。 Globing 由您正在运行的 shell 处理。因此scp user@machine:/path/*会将 /path/* 扩展到本地 /path/* 中的文件,而不是远程计算机上的文件。

然而,只是为了笑我尝试过:

scp "user@machine:/path/[regex here]" .  

并且......它起作用了。尝试一下。请注意引号。非常有必要。让我们知道。

注意:远程计算机上的用户帐户可能默认使用与其他计算机不同的 shell 程序你的,因此通配符扩展的规则可能会有所不同,因此请注意。

答案2

传递给的远程名称scp实际上被解释为远程端以空格分隔的模式列表。当您尝试复制名称包含空格的文件时,这通常会很麻烦,但在这里它很有用:scp -p 'user@machine:/path/a*' .将复制名称以a.

如果您引用该模式,以便远程而不是本地解释它,那么您的命令将起作用,前提是您通过了另一个障碍。该模式!(a*)不是基本的 shell 模式,而是 ksh 扩展(如果设置适当的选项,bash 和 zsh 也支持)。因此,只有当您的远程 shell 是 ksh 时,这才有效,而如果它是其他 shell 且您exec ksh来自.profile或类似的 shell,则此方法无效。

除非您处于某种受限制或古老的环境中,否则最简单的方法就是忘记scp.您希望远程文件像本地文件一样工作,因此将它们设为本地文件:使用以下命令挂载远程目录sshfs。这需要本地计算机上的 FUSE 和远程计算机上的SFTP 服务器(即启动的sftp-server可执行文件)。sshd

mkdir ~/net/machine
sshfs user@machine:/ ~/net/machine
cp -p ~/net/machine/path/!(a*) .

答案3

这不是“使用正则表达式的 scp”,处理文件 glob 的是 shell。scp只是得到已经扩展的文件列表。扩展发生在运行命令的机器上。

答案4

我发现,在较旧的 HP-UX 计算机(parisc 11.11)上,我必须使用 [^a]* 但是,在较新的计算机(parisc 11.31 及更新版本)上,它可以使用 !(a*)

这就是我最终得到的结果。它有效:

    if [[  ${S_MACH} = "phd026a" || ${S_MACH} = "tht030a" ]]
    then
            scp -p -r ${S_MACH}:${S_DIR}/bin/[^a^b^c^p]* ${D_DIR}/bin/.
    else
            scp -p -r ${S_MACH}:${S_DIR}/bin/!((a*)|(b*)|(c*)|(p*)) ${D_DIR}/bin/.
    fi

相关内容