如何仅同步特定文件列表?


93

我要推送到远程服务器的各个子目录中有大约50个左右的文件。我认为rsync可以使用--include-from选项为我执行此操作。如果没有--exclude =“ *”选项,则该目录中的所有文件都将同步,并且该选项不会同步任何文件。

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

我最初是干运行的,而0.0.0.0显然已被远程服务器的IP取代。rsync_include.txt的内容是换行分隔的新行列表,其中列出了要上传的文件的相对路径。

有没有更好的方法可以让我在星期一早上逃脱?

Answers:


3

编辑:下面的乔西德·罗丹的答案更好。请使用那个!

如果要查找文件的特定列表,可以将它们直接放在命令行上,这样可能会更轻松一些:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

但是,这是假设您的列表没有那么长,以至于命令行长度将成为问题,并且该rsync_include.txt文件仅包含实际路径(即,没有注释,也没有正则表达式)。


9
不幸的是,这不适用于大列表或名称中带有空格的文件。
Wes模式

3
[参数列表太长]
丹科·戴维

默认情况下,xargs将参数从stdin附加到命令行的末尾。这不起作用,因为rsync需要最后一个参数作为目标。某些版本的xargs可以选择将参数插入命令行中间。只要您不介意在文件列表很长的情况下rsync可能多次运行rsync,那它就应该起作用。无论如何,这rsync --files-from可能是一个更简单,更可靠的解决方案:)
Lassi,

Wes Hardaker:您对“ Josip Rodin的答案”的编辑和引用是否实际上引用了Rodin编辑的@atp答案
Seamus

228

有一个标志--files-from完全可以满足您的要求。来自man rsync

--files-from=FILE

使用此选项,您可以指定要传输的文件的确切列表(从指定的FILE读取或-对于标准输入)。它还调整了rsync的默认行为,以使仅传输指定的文件和目录更加容易:

  • 隐含--relative(-R)选项,该选项保留为文件中的每个项目指定的路径信息(如果要关闭,请使用--no-relative或--no-R)。

  • 隐含--dirs(-d)选项,它将创建目标列表中指定的目录,而不是吵杂地跳过它们(如果要关闭,请使用--no-dirs或--no-d)。

  • --archive(-a)选项的行为并不表示--recursive(-r),因此,如果需要,请明确指定它。

  • 这些副作用更改了rsync的默认状态,因此命令行上--files-from选项的位置与其他选项的解析方式无关(例如-a在--files-之前或之后的工作方式相同)以及--no-R和所有其他选项)。

从FILE读取的文件名都是相对于源目录的-删除任何前导斜线,并且不允许任何“ ..”引用高于源目录。例如,使用以下命令:

rsync -a --files-from=/tmp/foo /usr remote:/backup

如果/ tmp / foo包含字符串“ bin”(甚至是“ / bin”),则/ usr / bin目录将在远程主机上创建为/ backup / bin。如果它包含“ bin /”(请注意末尾的斜杠),则还将发送目录的立即内容(无需在文件中明确提及-从版本2.6.4开始)。在这两种情况下,如果启用了-r选项,该目录的整个层次结构也将被传输(请注意,-r需要用--files-from明确指定,因为-a并不隐含它)。还要注意,(默认情况下启用)-relative选项的作用是仅复制从文件读取的路径信息,它不会强制复制源规范路径(在这种情况下为/ usr) 。

另外,如果在文件前面指定“ host:”,则可以从远程主机而不是本地主机读取--files-from文件(主机必须与传输的一端匹配)。作为一种捷径,您可以仅指定前缀“:”来表示“使用传输的远端”。例如:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

这将复制/ path / file-list文件中位于远程“ src”主机上的所有文件。

如果指定了--iconv和--protect-args选项,并且--files-from文件名从一个主机发送到另一主机,则文件名将从发送主机的字符集转换为接收主机的字符集。

注意:对--files-from输入中的文件列表进行排序有助于rsync更加高效,因为它将避免重新访问相邻条目之间共享的路径元素。如果未对输入进行排序,则某些路径元素(隐含目录)可能最终会被扫描多次,并且rsync变成文件列表元素后,rsync最终将对其进行重复删除。


22
请注意,您仍然必须指定列出文件的目录,例如:rsync -av --files-from=file-list . target/用于从当前目录复制文件。
Nicolas Mattia

7
是的,并重申:The filenames that are read from the FILE are all relative to the source dir
atp 2016年

啊,错过了,对不起!
Nicolas Mattia

1
–如果文件中的文件具有以..rsync 开头的任何内容,似乎会忽略..给我的错误,例如rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(在这种情况下,从“ test”目录运行并尝试指定确实存在的“ ../subdir/test.txt”。
迈克尔

可以将--files-from参数与包括和排除的显式列表进行组合,并加入列表中的文件--files-from覆盖现有的排除规则,例如,如果他们出现在文件中它们被列入?
highsciguy

12

--files-from=如果要保持绝对路径完整,则参数需要在末尾加斜杠。因此,您的命令将如下所示:

rsync -av --files-from=/path/to/file / /tmp/

可以这样做,就像有大量文件,并且您要将所有文件复制到x路径一样。因此,您将找到文件,然后将输出抛出到如下文件:

find /var/* -name *.log > file

8

记录下来,除了一个答案,以上所有答案均无济于事。总而言之,您可以--files-from=使用以下任一方法执行备份操作:

 rsync -aSvuc`cat rsync-src-files` / mnt / d / rsync_test /

要么

rsync -aSvuc-递归--files-from = rsync-src-files。/ mnt / d / rsync_test /

前一个命令是不言自明的,在文件内容旁边rsync-src-files,我将在下面详细说明。现在,如果要使用后一个版本,则需要记住以下四个注意事项:

  1. 注意一个需要同时指定--files-from目录
  2. 需要明确指定--recursive
  3. 该文件rsync-src-files是用户创建的文件,已放置在此测试的src目录中
  4. rsyn-src-files所包含的文件和文件夹复制和它们相对于源目录中取。重要说明:确保文件中没有尾随空格或空白行。在下面的示例中,只有两行,而不是三行(偶然发现)。的内容rsynch-src-files是:

folderName1
folderName2


3

我得到了类似的任务:同步给定日期之后修改的所有文件,但不包括某些目录。要构建一种班轮多合一样式很困难,因此我将问题分解成小块。最终解决方案:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

首先我用find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS"。我尝试添加regexfind行中以排除名称模式,但是我的Linux(Mint)风格无法理解find。尝试过的正则表达式调味剂数量-无效。因此,我最终得到了egrep -v-选项,该选项不包括模式简便方法。我rsync没有复制/.cache/.config之类的目录,也没有复制我明确命名的其他目录。


1
我相信您可以使用流程替代将其变成bashrsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
单线

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

句法: rsync <file_/_folder_list> <source> <target>

文件夹名称(此处带尾随/;例如Cancer - Evolution/)位于文​​件夹列表文件中(例如:cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

如果不包括这些结尾/,则将创建rsync的目标文件夹,但它们为空。

这些文件夹名称将附加到其路径的其余部分(/home/victoria/Mail/2_RESEARCH - NEWS),从而为rsync提供完整的文件夹路径。例如:/home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/

请注意,您还需要使用--files-from=...,而不是--include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(在我的BASH脚本中,我$IN如下定义了变量。)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

使用的rsync选项:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

此答案不是问题的直接答案。但这可以帮助您确定哪种解决方案最适合您的问题。

分析问题时,应激活调试选项 -vv

然后rsync将输出哪种模式包含或排除哪些文件:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

当我只有目录列表时,这些答案都对我没有用。然后我偶然发现了解决方案!您必须添加-r--files-from因为-a在这种情况下(谁知道?!)将不会递归。

rsync -aruRP --files-from=directory.list . ../new/location

如果在文件中列出“ dir”,则需要指定-r / -recursive;如果列出“ dir /”,则不会。
lbutlr
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.