递归使用scp,但不包括某些文件夹


68

假设有一些具有这些结构的文件夹

/bench1/1cpu/p_0/image/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_0/fl_1/
/bench1/1cpu/p_1/image/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/1cpu/p_1/fl_1/
/bench1/2cpu/p_0/image/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_0/fl_1/
/bench1/2cpu/p_1/image/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
/bench1/2cpu/p_1/fl_1/
....

我想做的是scp以下文件夹

/bench1/1cpu/p_0/image/
/bench1/1cpu/p_1/image/
/bench1/2cpu/p_0/image/
/bench1/2cpu/p_1/image/

如您所见,我要递归使用,scp但要排除所有名为“ fl_X”的文件夹。看来scp没有这样的选择。

UPDATE scp没有这种功能。相反,我使用以下命令

 rsync -av --exclude 'fl_*' user@server:/my/dir

但这是行不通的。它只传输文件夹列表!就像是ls -R


2
查看rsync,它可以使用scp(或至少使用ssh)作为其传输机制,并支持从其参数中排除某些子目录。
chepner

2
这个可以吗?rsync -av --exclude 'fl_*' user@server:/my/dir .
mahmood

我认为这是正确的想法。我在评论中提到了这一点,因为我对自己的rsync技能不够自信,无法提供确切的答案。
chepner

没用 有人请查看更新的帖子
mahmood 2013年

你不能scp /bench1/1cpu/p_*/image/* remotehhost:/path/2/remote吗?祝好运。
shellter

Answers:


56

虽然 scp使用该-r选项支持递归目录复制,但它不支持文件过滤。有几种方法来完成你的任务,但我可能会依靠findxargstar和,ssh而不是scp

find . -type d -wholename '*bench*/image' \
| xargs tar cf - \
| ssh user@remote tar xf - -C /my/dir

rsync可以使该解决方案生效,但是您缺少一些参数。rsync还需要r切换到递归到子目录。另外,如果您想要相同的安全性scp,则需要在下进行传输ssh。就像是:

rsync -avr -e "ssh -l user" --exclude 'fl_*' ./bench* remote:/my/dir

2
那么“过滤”在哪里?您tar用于归档吗?
mahmood

find在我的解决方案中为您过滤。tar将要复制的目录打包在本地,然后在远程将其解包。
jxh

1
@ jgomo3:是的,您可以使用ssh和执行tar打包远程文件,并tar在本地使用解包文件。
jxh

2
@alonsos:该find命令标识与提供的模式匹配的目录并打印出来。该xargs命令读取输入并使它们成为该tar命令的参数,然后该命令将所有目录归档。该ssh命令连接到远程计算机并在远程计算机上执行tar,该命令会将归档文件解压缩到/my/dir目录中。
jxh

1
我将添加压缩以使网络数据尽可能小。更改tar cftar zcf。另请参见superuser.com/questions/305128/…
PatS

16

您可以指定GLOBIGNORE和使用模式*

GLOBIGNORE='ignore1:ignore2' scp -r source/* remoteurl:remoteDir

您可能希望拥有一些通用规则,可以使用来合并或覆盖这些规则export GLOBIGNORE,但对于临时使用,上述方法即可。该:字符用作多个值的定界符。


6
是否出口:GLOBIGNORE='ignore1:ignore2' scp -r source/* remoteurl:remoteDir
MartinŽdila18年

12

假设最简单的选项(在远程主机上安装rsync)不可行,则可以使用sshfs在本地安装远程,然后从安装目录进行rsync。这样,您可以使用rsync提供的所有选项,例如--exclude

这样的事情应该做:

sshfs user@server: sshfsdir
rsync --recursive --exclude=whatever sshfsdir/path/on/server /where/to/store

请注意,rsync的有效性(仅传输更改,而不是所有内容)在这里并不适用。这是因为要使其正常工作,rsync必须读取每个文件的内容以查看已更改的内容。但是,由于rsync仅在一台主机上运行,​​因此必须将整个文件传输到该主机上(通过sshfs)。但是,排除的文件不应传输。


工作,但--exlude param必须在rsync命令后放置;我面临的其他情况ERROR: destination must be a directory when copying more than 1 file
kellogs

它应该exclude=param代替exclude param
kellogs

1
奇怪的是,我的rsync版本不关心顺序。尽管如此,我还是对其进行了更改,以避免人们遇到问题。谢谢。
玛丽安

3

如果您使用pem文件进行身份验证,则可以使用以下命令(该命令将排除具有扩展名的文件):

rsync -Lavz -e "ssh -i <full-path-to-pem> -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --exclude "*.something" --progress <path inside local host> <user>@<host>:<path inside remote host>

-L表示跟随链接(复制文件而不是链接)。使用完整路径到您的pem文件,而不要使用相对路径。

不建议使用sshfs,因为它运行缓慢。另外,上面介绍的find和scp的组合也是一个坏主意,因为它将打开每个文件的ssh会话,这太昂贵了。


一个findscp可能需要的ssh每个文件会话。但这不是我的回答。
jxh

1

您可以按照以下示例使用扩展的globbing:

#Enable extglob
shopt -s extglob

cp -rv !(./excludeme/*.jpg) /var/destination

0

因为目录结构对我来说并不重要,所以这对我来说很好用。

scp -r USER@HOSTNAME:~/bench1/?cpu/p_?/image/ .

假设/bench1位于当前用户的主目录中。另外,将USER和HOSTNAME更改为真实值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.