2013-03-19 116 views
-3

我对python非常陌生,每天都会学到很多东西。 我想做一个自动脚本,这将有助于我的工作。在目录中搜索包含文件夹路径的特定文件并将其复制到Python中

我有一个包含一些文件的特定文件夹,我不希望我的工具,是具体的文件,因为我想,所以我希望它在文件中查找特定的标题重复使用这个脚本,

可以说文件在中间的某处有“路径”,在它的下面有很多路径,比如“file path =”Some path“

我希望我的脚本进入我指定的目录并查找包含这个标题“路径” 复制其中一条路径(它们将在它下面)并且就是它。

然后我去要使用此路径下载文件和更多,但这部分我已经完成。 我只是不知道如何在给定特定文件夹时查找文件中的特定字符串并复制我想要的字符串。

所以,可以说,我有一个文件夹(C:\文件夹) ,文件夹中,我有3个文件(1,2,3)

我想寻找含有这种模式的文件“路径“ 并复制路径或其中至少一个指定的路径。 他们会像 “文件路径= C:\ somepath” 所以文件内容是像

布拉布拉

布拉布拉

路径

文件路径= C:\ somepath

file path = C:\ somepath2

blabla

我想复制C:\ somepath并将其用作我工作的一部分。

非常感谢所有帮手,这对我来说更重要。

+0

好吧,如果你期待帮助,你应该先用适当的英语解释你的问题。 现在,不可能遵循你想说的话,用你的标点和语法搞砸了。 – geenux 2013-03-28 00:12:24

回答

1

第一步是查看目录中的所有文件。那是os.listdir

接下来,您需要在循环中打开每个文件。所以,到目前为止,我们得到了:

for filename in os.listdir(directory): 
    with open(filename) as f: 

现在,我们对每个文件做什么?有几个不同的选项 - 我们可以在整个文件(或mmap它)中读取,然后使用str.find或正则表达式方法来解析它,或者我们可以一行一行地跟踪我们的状态,或者我们可以转换我们可以建立一个状态机并运行它,或者...

我认为对于新手来说最简单的就是手动逐行执行。但让我们把它包装在一个函数中。所以:

def parse_file(f): 
    paths = [] 
    found_paths = False 
    for line in f: 
     line = line.strip() 
     if not found_paths: 
      if line == 'paths': 
       found_paths = True 
     else: 
      if line.startswith('file path='): 
       paths.append(line[len('file path='):]) 
      else: 
       break 
    return paths 

paths = [] 
for filename in os.listdir(directory): 
    with open(filename) as f:    
     paths.append(parse_file(f)) 

我怎样才能找到第一个行后停止?

只读break看完第一行后。所以,与其这样:

if line.startswith('file path='): 
    paths.append(line[len('file path='):]) 
else: 
    break 

这样做:

if line.startswith('file path='): 
    paths.append(line[len('file path='):]) 
break 

我怎么能解决这个问题就摆在不同的指数的路径在字典中,因为它把所有的人都在第一场

那么现在,你是不是创建一个字典,你要创建一个列表。

如果您想要一个字典,将每个文件映射到该文件中的文件路径列表,这很容易。取而代之的是:

paths = [] 
for filename in os.listdir(directory): 
    with open(filename) as f: 
     paths.append(parse_file(f)) 

这样做:

paths = {} 
for filename in os.listdir(directory): 
    with open(filename) as f:    
     paths[filename] = parse_file(f) 

但是,它可能是简单的不能建立在首位的列表,如果你只想要一个值。如果你找到一个,你只需要返回路径名,如果你不这样做的话,它不可能是一个路径名(如None)。

我该如何修改有问题的路径。因为文件的路径保存在这种格式 - 我只想复制C:\文件夹\文件夹

嗯,首先,我的代码甚至不会找到与该格式事情。您要求找到像file path=…这样的行,因此我使用了startswith,但<file path=不以此开头。所以你首先需要改变你检查的startswith。同时,您还需要处理引号和尖括号。

在这一点上,它看起来像只是愚蠢的文字处理可能不是正确的答案。这看起来像XML。解析XML文档的最简单方法是使用XML解析器,如xml.elementtree。如果它不是一个XML文件,只要有卡在它的XML节点基于行的文件,你可以仍然尝试解析每行一个XML文档,但它可能是更容易使用re用合适的正则表达式(例如,r'<file path="(.*?)"/>'将仅匹配引号之间的部分)。不知道你的实际输入文本的样子,我不能给你任何东西比这更具体。

最后,在完成该步骤后,它看起来像要从目录路径中删除尾部反斜杠,所以即使该文件有C:\folder\folder\,也会得到C:\folder\folder。你可以在os.path此使用的功能,但如果你确定的路径总是会在Windows格式,它可以更简单,只是告诉它删除任何尾随的反斜杠,与rstrip('\\')。 (请注意那里的双反斜杠,因为您需要在Python字符串中跳出反斜杠。)

+0

非常感谢,但我有几个问题。如何在找到第一行后停下来?或者我可以如何修复它把路径放在字典中的不同索引中,因为它将所有这些路径放在第一个字段中(并且最终我想使用它)第二个问题是如何修改有问题的路径。因为文件中的路径以这种格式保存 - <文件路径=“C:\文件夹\文件夹\”/>,我只想复制C:\文件夹\文件夹。谢谢!!! – 2013-03-20 00:31:01

+0

既然你有很多问题,让我更新答案。 – abarnert 2013-03-20 00:50:09

+0

好吧,不需要第一个问题的答案,我只是做路径[0] [0]但我如何操纵路径,脚本的结果现在是文件中的“C:\ folder \ folder \”/>它是<文件路径=“C:\文件夹\文件夹\”/> - 我想要的结果是C:\文件夹\文件夹 - 谢谢! – 2013-03-20 00:50:30

-1

根据您的意见,您的数据实际上是XML,而您想要的是第一个paths节点中每个(或第一个)节点的path属性。

就XML解析器而言,这实际上更容易编写,并且更加健壮。

例如,这些可能都有效file节点:

<file path="C:\Foo\Bar" /> 
<file path="C:\Baz\Qux"/> 
    <file path="C:\Foo\Bar" /> 
<file path="C:\Spam\Eggs\" alt="other attribute cruft" /> 
<file alt="other attribute cruft" path="C:\Spam\Eggs\" /> 
<file path="C:\Spam\Spam\"></file> 

而且你甚至可以看到这些,合法与否:

<file path='C:\Eggs\"Spam Spam Spam"\"Spammity Spam"'/> 

你不想尝试处理所有在纯文本中的可能性。但是,如果你不处理所有这些 - 而且更重要的是 - 墨菲定律可以保证你最终会碰到一个你无法处理的文件。

有很多不同的XML解析器,甚至内置到标准库中,但我认为最简单的是ElementTree。所以:

import os 
import os.path 
import xml.etree.ElementTree as ET 

filepaths = {} 
for filename in os.listdir(directory): 
    try: 
     doc = ET.parse(os.path.join(directory, filename)) 
     paths = doc.find('paths') 
     filepaths[filename] = [f.attrib['path'] for f in paths.findall('file')] 
    except Exception as e: 
     # You may want to log something, treat different exceptions differently, etc. 
     pass 

这应该是很容易弄清楚如何改变这种处理所有paths节点,而不是第一个,或paths,而不是所有的人都在第一file节点,或第一file节点时具有path属性等

如果您使用的是Python 2.x,并且这些文件非常大,则可能会有点慢。但是你可以通过明确使用cElementTree来解决这个问题。这是很常见的做到这一点:

try: 
    import xml.etree.cElementTree as ET 
except ImportError: 
    import xml.etree.ElementTree as ET 

如果可能会给你快“C”的实施,缓慢的一个,否则,在CPython的2.5+(包括3.x中,其中两个被合并在一起) PyPy等


同时,从其他意见,你要的那种没有在原来的岗位额外的东西:

我只需要......使反斜杠/

这很简单。请在每个路径s上拨打s.replace('\\', '/')

但是,这是一件很奇怪的事情。其他方式很常见(它甚至内置于标准库中 - os.path.normpath将在POSIX上单独使用斜杠,但将它们转换为Windows上的反斜杠),但从本地Windows到POSIX通常是较大操作的一部分,比如构建一个URL ......在这种情况下,您可能想要使用更高级别的功能。

它在文件中

- 结果我要的是C:\文件夹\文件夹

这里,这听起来像你想去掉所有斜杠。再一次,这是一件很奇怪的事情,你可能实际上想要做比这更高级的事情(比如os.path.dirname也许?),但很容易:s.rstrip('\\')

当然这些最后两个相互矛盾 - 如果你想要的结果是C:\folder\folder,并且你将反斜杠转换为正斜杠,你不会得到你想要的结果。

但希望我给了你足够的建设,无论你真正想要什么。

+0

我不知道我做错了什么,我的文件看起来像这样 - 和它下面<文件路径=“C:\文件夹\文件夹\”/>和更多路径在相同的格式,它结束后在文件的顶部,在底部还有更多的东西。我运行你写的代码,我在filepaths中得到的代码是空的{},并且在我得不到的路径中。行! – 2013-03-20 02:57:04

+0

行!我得到了解决方案!谢谢你的出色帮助! – 2013-03-20 03:23:42

+0

谁低估,谨慎解释为什么? – abarnert 2013-03-20 19:07:27

相关问题