【问题标题】:Rsync filters in a python looppython循环中的rsync过滤器
【发布时间】:2016-06-22 00:01:34
【问题描述】:

阅读有关过滤规则的手册页并查看此处: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=- * 不匹配的文件

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

编辑:我正在使用 rsync 版本 3.1.0 进行测试,发现与早期版本不兼容。

这是一个工作代码的链接,您应该可以将其粘贴到 Python 解释器中以获得“试运行”的结果,它不会将任何内容下载到您的计算机上:http://pastebin.com/0reVKMCg 它在 @ 下得到了一切987654336@,这不是我想要的。如果我在 '-f=- *' 未注释的情况下运行该脚本,它什么也得不到,这似乎与这里的答案相矛盾 Using Rsync filter to include/exclude files

【问题讨论】:

  • 您确定可以通过 FTP 使用rsync 吗?:serverfault.com/questions/24622/how-to-use-rsync-over-ftp
  • 是的,我确定。我有一个类似的脚本运行良好,直到我意识到我得到的一些文件(根据我的过滤器)是我不想要的文件。
  • hmm,您能否发布有效的 sn-p 以便我们获得示例输出,然后进一步阐明您要过滤的内容?
  • 当然 - 感谢您的提问!这个pastebin.com/0reVKMCg 有效,但看起来它在ftp.ncbi.nlm.nih.gov::genomes/genbank/bacteria/'+latest 下得到了一切。如果我在 '-f=- *' 未注释的情况下运行该脚本,它什么也得不到,这似乎与stackoverflow.com/questions/35364075/… 的答案相矛盾
  • 运行 pastebin 并没有为我生成任何东西...

标签: python ftp subprocess rsync


【解决方案1】:

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

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

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

+ /文件包含

-*

这会失败,因为父目录“some”被 '*' 规则排除,所以 rsync 永远不会访问任何 “some”或“some/path”目录中的文件。一种解决方案是询问目录中的所有目录 通过使用单个规则来包含层次结构:“+ */”(将其放在“- *”规则之前的某个位置),并按照 可能使用 --prune-empty-dirs 选项。另一种解决方案是为所有 需要访问的父目录。例如,这组规则可以正常工作:

+ /一些/

+ /一些/路径/

+ /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, 不适用于尾随 / 之后的 *。虽然它只适用于没有* 的尾随/

【讨论】:

    猜你喜欢
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多