如何修改此rsync命令以查找带有';的目录';用Python?
我在python中使用rsync命令,如下所示:如何修改此rsync命令以查找带有';的目录';用Python?,python,rsync,python-2.6,Python,Rsync,Python 2.6,我在python中使用rsync命令,如下所示: rsync_out = subprocess.Popen(['sshpass', '-p', password, 'rsync', '--recursive', source], stdout=subprocess.PIPE) command = subprocess.Popen(('grep', '\.'), stdin=rsync_out.stdout, stdout=subproc
rsync_out = subprocess.Popen(['sshpass', '-p', password, 'rsync', '--recursive', source],
stdout=subprocess.PIPE)
command = subprocess.Popen(('grep', '\.'), stdin=rsync_out.stdout, stdout=subprocess.PIPE).communicate()[0]
rathi/20090209.02s1.2_sequence.txt
rathi/20090729.02s4.2_sequence.txt.gz
rathi/Homo_sapiens_UCSC_hg19.tar.gz
rathi/hello/ok.txt
rathi/hello.v1/ok.txt
drwxr-xr-x 4096 2013/06/14 17:19:13 tmp/t
-rwxrwxr-x 14532 2013/06/14 17:17:23 tmp/t/a.out
-rwxrwxr-x 14539 2013/06/14 17:19:13 tmp/t/static-order
使用grep显示文件的目的如下:
rsync_out = subprocess.Popen(['sshpass', '-p', password, 'rsync', '--recursive', source],
stdout=subprocess.PIPE)
command = subprocess.Popen(('grep', '\.'), stdin=rsync_out.stdout, stdout=subprocess.PIPE).communicate()[0]
rathi/20090209.02s1.2_sequence.txt
rathi/20090729.02s4.2_sequence.txt.gz
rathi/Homo_sapiens_UCSC_hg19.tar.gz
rathi/hello/ok.txt
rathi/hello.v1/ok.txt
drwxr-xr-x 4096 2013/06/14 17:19:13 tmp/t
-rwxrwxr-x 14532 2013/06/14 17:17:23 tmp/t/a.out
-rwxrwxr-x 14539 2013/06/14 17:19:13 tmp/t/static-order
而不是
rathi
rathi/20090209.02s1.2_sequence.txt
rathi/20090729.02s4.2_sequence.txt.gz
rathi/Homo_sapiens_UCSC_hg19.tar.gz
hello
rathi/hello/ok.txt
它可以正常工作,除非目录名上有。
如果有一个名为hello.v1的目录,则输出为:
rathi/hello.v1
rathi/hello.v1/ok.txt
因为hello.v1是一个目录名,所以我只想这样显示:
rsync_out = subprocess.Popen(['sshpass', '-p', password, 'rsync', '--recursive', source],
stdout=subprocess.PIPE)
command = subprocess.Popen(('grep', '\.'), stdin=rsync_out.stdout, stdout=subprocess.PIPE).communicate()[0]
rathi/20090209.02s1.2_sequence.txt
rathi/20090729.02s4.2_sequence.txt.gz
rathi/Homo_sapiens_UCSC_hg19.tar.gz
rathi/hello/ok.txt
rathi/hello.v1/ok.txt
drwxr-xr-x 4096 2013/06/14 17:19:13 tmp/t
-rwxrwxr-x 14532 2013/06/14 17:17:23 tmp/t/a.out
-rwxrwxr-x 14539 2013/06/14 17:19:13 tmp/t/static-order
我怎么能做到这一点呢?就我个人而言,我不想麻烦使用
grep
,我只想使用Python自己的字符串过滤——然而,这不是你问的问题
由于文件名是远程的,Python只将其视为字符串,因此我们不能使用Python自己的任何文件操作例程(例如,os.path.isdir()
)。因此,我认为有三种基本方法:
rsync
中的元信息rsync
的经验,它通常会提供如下完整的文件信息:
rsync_out = subprocess.Popen(['sshpass', '-p', password, 'rsync', '--recursive', source],
stdout=subprocess.PIPE)
command = subprocess.Popen(('grep', '\.'), stdin=rsync_out.stdout, stdout=subprocess.PIPE).communicate()[0]
rathi/20090209.02s1.2_sequence.txt
rathi/20090729.02s4.2_sequence.txt.gz
rathi/Homo_sapiens_UCSC_hg19.tar.gz
rathi/hello/ok.txt
rathi/hello.v1/ok.txt
drwxr-xr-x 4096 2013/06/14 17:19:13 tmp/t
-rwxrwxr-x 14532 2013/06/14 17:17:23 tmp/t/a.out
-rwxrwxr-x 14539 2013/06/14 17:19:13 tmp/t/static-order
在您的示例中,我看不到任何删除此附加信息的代码,您可以通过查找以d
而不是-
开头的任何行,轻松使用此代码筛选出目录
如果您没有此扩展信息,则需要执行另外两个操作之一。第一个选项非常简单——只需按斜杠拆分,然后向下移动一个标准树结构,为尚未看到的目录和文件添加条目。解析完所有条目后,就可以遍历树并打印出没有子节点的任何节点
第二个选项更复杂,但内存效率更高,您可以维护父目录列表,并检查它们是否是列表中当前项的前缀。如果是这样,您可以确保前一个是目录,当前一个是文件,因此您可以将前一个标记为不显示的内容。如果rsync
以可预测的顺序返回项目,则在递归“退出”该目录后,也可以将项目从该列表中删除。您必须确保只检查斜杠边界处的前缀(因此foo/dir
不是foo/dir bar
的父项,而是foo/dir/bar
的父项)。一般来说,这种方法相当复杂,除非您处理的是非常大的目录树,否则其他方法之一可能更可取
顺便说一下,这两种纯基于字符串的方法都有一个缺点,即空目录与文件无法区分,因为只有目录中是否存在文件才能区分它们。这是我建议使用rsync
中的元信息的另一个原因
编辑
根据要求,使用rsync
元数据的示例如下:
import subprocess
cmdline = ["rsync", "-e", "ssh", "-r", "user@host:/dir"]
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
for entry in proc.stdout:
items = entry.strip().split(None, 4)
if not items[0].startswith("d") and "." in items[4]:
print items[4]
在本例中,我直接调用rsync
,并让它使用ssh
,假设设置了适当的ssh密钥。我强烈建议使用SSH密钥而不是sshpass
实用程序-从安全角度来看,以明文形式存储密码是一个非常糟糕的主意。如果你不担心钥匙被盗,你可以设置钥匙,但不需要密码。有很多页面解释如何创建SSH密钥(例如)
将user
、host
和/dir
替换为远程计算机上的用户名、远程计算机的主机名和要在远程计算机上列出的父目录(如果要列出用户的主目录,可以省略/dir
)。否则,代码将不经修改地运行。If将打印它找到的每个文件的路径名,跳过不包含点的目录和项目。如果您的点过滤器也只是试图跳过目录,则可以在项目[4]中省略“和”。”
编辑2
本例仅打印条目,但当然您可能需要执行其他操作。如果你真的想变得聪明,你可以把它写成一个生成器,在项目出现时调用yield
。我在下面有一个例子,它也会打印项目,但是你可以看到它是如何被用来做其他事情的。我还添加了一些更好的错误处理,以确保子流程的使用不会死锁:
编辑3:我已经更新了这个示例,包括文件大小和修改时间。这是基于我从rsync
中得到的信息-如果您的格式不同,您可能需要使用items
中的不同成员,或者可能将格式字符串更改为strptime()
,以匹配rsync
返回的格式
您应该能够将整个find_remote_files()
函数粘贴到您的代码中,并直接使用它,如果您愿意的话。谢谢您的精彩回答。我更喜欢第三种方法。你能给我举个例子吗。谢谢我在我的帖子中添加了几个例子,希望能回答你的问题。我建议使用第二个函数中的生成器函数,希望示例能够清楚地说明如何使用它。这一个比第一个稍微复杂一点,但它处理一些罕见的终止情况,如果rsync
发生错误,在第一个示例中可能会导致死锁。感谢您的精彩回答,但我想知道大小和