使用scp递归复制dir时如何过滤文件?


99

我需要将所有.class文件从服务器复制到本地,并保留所有目录。例如,server:/usr/some/unknown/number/of/sub/folders/me.class/usr/project/backup/some/unknown/number/of/sub/folders/me.class可问题是,还有许多其他无用的文件,如的.svn基文件我不想。我该如何过滤它们,以便仅使用scp.class文件?


我喜欢提到的rsync选项。您没有提到这是否是一次性操作,或者是否将重复执行此自动化操作。对于一次性操作,明智地使用find,grep -v,xargs和临时文件应该可以简化此工作。
2009年

Answers:


152

rsync由于其includeexclude标志,我可能建议为此使用类似的东西,例如:

rsync -rav -e ssh --include '*/' --include='*.class' --exclude='*' \
server:/usr/some/unknown/number/of/sub/folders/ \ 
/usr/project/backup/some/unknown/number/of/sub/folders/

其他一些有用的标志:

  • -r 用于递归
  • -a 用于存档(主要是所有文件)
  • -v 用于详细输出
  • -e 指定ssh而不是默认值(实际上应该是ssh)

4
无论如何要使其忽略其中没有* class文件的子文件夹?(即,我不要一堆空目录)
Grant Birchmeier

太棒了,而且它也非常邪恶!
Prasad Chalasani 2014年

2
您能解释--include,不是--include =在手册页中,我可以在--include =而不是--include上找到解释
bazz 2014年

1
根据rsync手册页,该选项-a已包含在内-r
GeorgSchölly17年

3
@GrantBirchmeier --prune-empty-dirs将删除空目录。
Elrond1337 '18

74

要在基本目录中排除点文件:

scp -r [!.]* server:/path/to/something

[!.]* 是一个外壳文件,可扩展到工作目录中的所有文件,而不以点开头。


10
这可能是最好的答案。使用glob过滤文件是一种方法。
Yoshua Wuyts 2015年

1
如果您的选择像我一样仅限于scp,那么这绝对有帮助。
user28095 2015年

3
这表示要排除被询问的文件,但是如何在整个目录中实现呢?
皮尔

37

scp中没有过滤文件的功能。对于像这样的“高级”东西,我建议使用rsync:

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

(此行将rsync从远程文件夹复制到当前文件夹)

默认情况下,ssync连接上的rsync隧道的最新版本是自动的。


10

既然你可以scp,你应该确定ssh
无论是脚本以下或登录并执行...

# After reaching the server of interest
cd /usr/some/unknown/number/of/sub/folders
tar cfj pack.tar.bz2 $(find . -type f -name *.class)

返回(注销)到本地服务器,然后scp

# from the local machine
cd /usr/project/backup/some/unknown/number/of/sub/folders
scp you@server:/usr/some/unknown/number/of/sub/folders/pack.tar.bz2 .
tar xfj pack.tar.bz2

如果您发现$(find ...)tar太长而无法更改为tar,

find . -type f -name *.class | xargs tar cfj pack.tar.bz2

最后,既然您将其保留在其中/usr/project/backup/
为什么还要麻烦提取呢?只需保留tar.bz2,可能要加上日期和时间戳。


这对我有帮助。我在Windows中,正在努力尝试在OS上进行安装rsyncssh安装。相反,这是一个聪明的解决方法。谢谢!
rayryeng

2

以下命令用于文件。

scp`查找。-maxdepth 1 -name“ * .log” \!-名称“ hs_err_pid2801.log”-键入f` root @ IP:/ tmp / test /

  1. IP将是目标服务器的IP地址。
  2. -name“ * .log”用于包含文件。
  3. \!-name“ hs_err_pid2801.log”表示排除文件。
  4. 。是当前的工作目录。
  5. -f为文件类型。

下面的命令用于目录。

scp -r`find。-maxdepth 1-名称“ lo *” \!-名称“本地主机”-键入d` root @ IP:/ tmp / test /

您可以根据需要自定义上述命令。


1

启用基于ssh密钥的身份验证后,以下脚本将起作用。

for x in `ssh user@remotehost 'find /usr/some -type f -name *.class'`; do y=$(echo $x|sed 's/.[^/]*$//'|sed "s/^\/usr//"); mkdir -p /usr/project/backup$y; scp $(echo 'user@remotehost:'$x) /usr/project/backup$y/; done

1

如果您确实想使用scp,则有一种间接方法。假设我们要将本地文件夹“ / src”下的所有.jpg文件复制到远程服务器10.1.1.2中的文件夹“ / dst”:

#make a clean temp folder
mkdir /tmp/ttt
#copy all .jpg file and retain folder structure as-is
find /src -type f -name *.jpg -exec cp --parents \{\} /tmp/ttt \;
#copy to remote target folder as-is and retain original time attributes
scp -rp /tmp/ttt/* 10.1.1.2:/dst
#if copy ok, remove temp folder
rm -rf /tmp/ttt

0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path

1
口头解释和代码也很有帮助
con

-1
  1. 将您的源文件夹复制到somedir

    cp -r srcdir somedir

  2. 删除所有不需要的文件:

    找到somedir -name'.svn'-exec rm -rf {} \ +

  3. 从启动scp somedir


为什么所有对这个答案的否决?这听起来像是问题的通行解决方案。
bcarroll

7
因为这样会复制大量不必要的文件,然后将其删除,因此可能会浪费大量时间。
奥德

对于经过多个编译步骤的程序,这实际上很有意义。它可能就在将编译后的代码打包到一个tarzip-file文件中的步骤之前。相反,没有压缩(scp进行压缩),并且“打包的”代码被复制过来。
samvv

没错,@ samvv(取决于设置,环境)
San Jay Falcon

如果由于空间限制而忽略了文件,则会浪费空间和时间
杰克
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.