Rsync在python循环中过滤

时间:2016-06-22 00:01:34

标签: python ftp subprocess rsync

阅读有关过滤规则的手册页并查看此处:Using Rsync filter to include/exclude files

我不明白为什么下面的代码不起作用。

import subprocess, os
from ftplib import FTP

ftp_site = 'ftp.ncbi.nlm.nih.gov'
ftp = FTP(ftp_site)
ftp.login()
ftp.cwd('genomes/genbank/bacteria')
dirs = ftp.nlst()

for organism in dirs:
    latest = os.path.join(organism, "latest_assembly_versions")
    for path in ftp.nlst(latest):
        accession = path.split("/")[-1]
        fasta = accession+"_genomic.fna.gz"
        subprocess.call(['rsync',
                         '--recursive',
                         '--copy-links',
                         #'--dry-run',
                         '-vv',
                         '-f=+ '+accession+'/*',
                         '-f=+ '+fasta,
                         '-f=- *',
                         'ftp.ncbi.nlm.nih.gov::genomes/genbank/bacteria/'+latest,
                         '--log-file=scratch/test_dir/log.txt',
                         'scratch/' + organism])

我还尝试'--exclude=*[^'+fasta+']'尝试排除与fasta不匹配的文件,而不是-f=- *

对于path中的每个目录latest/*,我希望文件与fasta完全匹配。目录fasta中始终只有一个文件latest/path

编辑:我正在使用 rsync 3.1.0版对此进行测试,并发现早期版本存在不兼容问题。

这是一个指向工作代码的链接,您应该能够将其粘贴到python解释器中以获得“干运行”的结果,该结果不会将任何内容下载到您的计算机上:http://pastebin.com/0reVKMCg它可以获得一切在ftp.ncbi.nlm.nih.gov::genomes/genbank/bacteria/'+latest下,这不是我想要的。如果我在没有注释'-f=- *'的情况下运行该脚本,它就不会得到任何东西,这似乎与此处的答案相矛盾Using Rsync filter to include/exclude files

1 个答案:

答案 0 :(得分:0)

rsync手册页的这一部分包含解决问题所需的信息:

  

注意,当使用--recursive(-r)选项(由-a隐含)时,每个子组件都是   从上到下访问路径,因此包含/排除模式递归应用于每个子组件 -   nent的全名(例如包括“/ foo / bar / baz”子组件“/ foo”和“/ foo / bar”一定不能   除外)。当rsync找到时,排除模式实际上会使目录遍历阶段短路   要发送的文件。如果一个模式排除了一个特定的父目录,它可以呈现更深层次的包括   因为rsync没有通过层次结构的排除部分下降而导致无效。这是   使用尾随'*'规则时尤为重要。例如,这不起作用:

     

+ / some / path / this-file-will-not-be-found

     

+ / file-is-included

     

- *

     

这会失败,因为'*'规则排除了父目录“some”,因此rsync永远不会访问任何一个   “some”或“some / path”目录中的文件。一种解决方案是询问中的所有目录   要使用单个规则包含的层次结构:“+ * /”(将其放在“ - *”规则之前的某处),并且   haps使用--prune-empty-dirs选项。另一种解决方案是为所有人添加特定的包含规则   需要访问的父母dirs。例如,这套规则运行正常:

     

+ / some /

     

+ / some / path /

     

+ / some / path / this-file-is-found

     

+ / file-also-included

     

- *

这有助于我编写以下代码:

def get_fastas(local_mirror="scratch/ncbi", bacteria="Escherichia_coli"):
        ftp_site = 'ftp.ncbi.nlm.nih.gov'
        ftp = FTP(ftp_site)
        ftp.login()
        ftp.cwd('genomes/genbank/bacteria')
        rsync_log = os.path.join(local_mirror, "rsync_log.txt")
        latest = os.path.join(bacteria, 'latest_assembly_versions')
        for parent in ftp.nlst(latest)[0:2]:
                accession = parent.split("/")[-1]
                fasta = accession+"_genomic.fna.gz"
                organism_dir = os.path.join(local_mirror, bacteria)
                subprocess.call(['rsync',
                                '--copy-links',
                                '--recursive',
                                '--itemize-changes',
                                '--prune-empty-dirs',
                                '-f=+ '+accession,
                                '-f=+ '+fasta,
                                '--exclude=*',
                                'ftp.ncbi.nlm.nih.gov::genomes/genbank/bacteria/'+parent,
                                organism_dir])

结果'-f=+ '+accession,结果*在跟踪/后无效/。虽然它只适用于没有*

的尾随{{1}}