2016-06-22 14 views
1

Nachdem die Manpage auf Filterregeln zu lesen und suchen hier: Using Rsync filter to include/exclude filesRsync Filter in einem Python-Schleife

Ich verstehe nicht, warum der folgende Code funktioniert nicht.

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]) 

Ich habe auch versucht '--exclude=*[^'+fasta+']' zu versuchen, Dateien auszuschließen, die fasta nicht statt -f=- *

die fasta Für jedes Verzeichnis path innerhalb latest/*, möchte ich die Datei entsprechen genau übereinstimmt. Es wird immer genau eine Datei fasta im Verzeichnis latest/path sein.

EDIT: Ich teste diese mit rsync Version 3.1.0 und haben mit früheren Versionen Kompatibilitätsprobleme gesehen.

Hier ist ein Link zu Code arbeiten, sollten Sie in ein Python-Interpreter einfügen können, um die Ergebnisse eines bekommen „Trockenlauf“, was alles nicht auf Ihren Computer herunterladen werden: http://pastebin.com/0reVKMCg es alles unter ftp.ncbi.nlm.nih.gov::genomes/genbank/bacteria/'+latest bekommt, was ich nicht will. und wenn ich das Skript mit '-f=- *' unkommentiert laufen, ist es nicht alles bekommen, was die Antwort hier Using Rsync filter to include/exclude files

+0

funktioniert Sind Sie sicher, dass Sie 'rsync' über FTP verwenden können ?: http://serverfault.com/questions/24622/how-to-use-rsync-over -ftp –

+0

Ja, da bin ich mir sicher. Ich hatte ein ähnliches Skript, das wunderbar funktionierte, bis mir klar wurde, dass einige der Dateien, die ich erhielt (nach meinen Filtern), Dateien waren, die ich nicht haben wollte. – truthling

+0

hmm, könnten Sie das Arbeits-Snippet posten, damit wir eine Beispielausgabe erhalten und dann weiter erläutern können, was Sie filtern möchten? –

Antwort

0

Dieser Teil des rsync Manpage enthalten die Informationen zu widersprechen scheint, dass ich brauchte, um mein Problem zu lösen:

Beachten Sie, dass bei Verwendung der Option --recursive (-r) (die durch -a angegeben wird) jede Unterkomponente jedes Pfades von oben nach unten besucht wird, sodass Einschluss-/Ausschlussmuster rekursiv auf jede Unterkompo- nente angewendet werden. nents voller Name (zB um "/ foo/bar/baz" einzuschließen, dürfen die Unterkomponenten "/ foo" und "/ foo/bar" nicht ausgeschlossen werden). Die Ausschlussmuster schließen die Verzeichnisdurchlaufstufe tatsächlich kurz, wenn rsync die zu sendenden Dateien findet. Wenn ein Muster ein bestimmtes übergeordnetes Verzeichnis ausschließt, kann dies dazu führen, dass ein tieferliegender Include-Prozess unwirksam wird, weil rsync nicht durch diesen ausgeschlossenen Abschnitt der Hierarchie abgestiegen ist. Dies ist besonders wichtig, wenn Sie eine nachgestellte '*' Regel verwenden. Zum Beispiel wird dies nicht funktionieren:

+/some/path/this-Datei-will-nicht-sein-gefunden

+/file-ist-inklusive

- *

Dies schlägt fehl, da das übergeordnete Verzeichnis "einige" durch die Regel "*" ausgeschlossen wird. Daher ruft rsync nie die Dateien in den Verzeichnissen "some" oder "some/path" auf. Eine Lösung besteht darin, alle Verzeichnisse in der Hierarchie einzubeziehen, indem Sie eine einzige Regel verwenden: "+ * /" (setzen Sie sie irgendwo vor die "- *" Regel), und per haben Sie die --prune- Leer-Option. Eine andere Lösung besteht darin, spezifische Include-Regeln für alle übergeordneten Verzeichnisse hinzuzufügen, die besucht werden müssen.Zum Beispiel dieser Satz von Regeln funktioniert:

+/some/

+/some/path/

+/some/path/this-Datei-is-gefunden

+/file-auch Inklusions

- *

das half mir den folgenden Code schreiben:

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]) 

Es stellt sich heraus '-f=+ '+accession, nicht mit einem * funktioniert nach dem / Hinter. Obwohl es nur mit einem / ohne *