【问题标题】:Copying selected lines from files in different directories to another file将选定行从不同目录中的文件复制到另一个文件
【发布时间】:2018-04-21 01:35:18
【问题描述】:

我有一个包含许多子目录的目录,其中包含文件。我想在“App_integrations”文件夹中打开以“root.vrpj”或“root.vprj”结尾的文件,并将包含“table”一词的行复制到另一个文件中。

到目前为止,我已经设法使用此代码访问每个文件:

for root, dirs, files in os.walk(movedir):
for filename in files:
    if filename.endswith(("root.vrpj", "root.vprj")):

问题是我现在拥有的只是我想访问的文件的名称,我被困在这里。

【问题讨论】:

  • 您可以使用with open("filename","r") as readFile 打开文件,然后使用for line in readFile 遍历文件中的行,这可能会让您进一步开始docs.python.org/2/tutorial/inputoutput.html,快乐编码:)

标签: python python-2.7 copy file-copying


【解决方案1】:

你可以试试这个:

f = open('final_file.txt', 'w')
for root, dirs, files in os.walk(movedir):
   for filename in files:
      if filename.endswith("root.vrpj") or  filename.endswith("root.vprj"):
         with open(filename) as data:
            for line in data:
               if "table" in data:
                   f.write('{}\n'.format(data))
f.close()

【讨论】:

  • 你应该尽可能提倡使用with,这样代码更简洁。
  • 别忘了外面的那个。 ;) 你有很多级联语句。
  • 如果任何行包含"table",您还将整个输入文件写入f...
  • 没用。我看到的一个问题是您没有使用 os.path.join 来获得要读取的文件的完整路径(这似乎是必要的)
【解决方案2】:

这是 Ajax 代码的一个版本,可以关闭您在循环中打开的文件(并修复了一些其他小问题):

with open('final_file.txt', 'w') as f:
    for root, dirs, files in os.walk(movedir):
        for filename in files:
            if filename.endswith(("root.vrpj"), ("root.vprj")):
                with open(os.path.join(root, filename)) as finput:
                     for line in finput:
                         if 'table' in line:
                             f.write(line)

但是,当您看到 8 级缩进时,您需要重构,例如:

def find_files(startdir, *extensions):
    for root, dirs, files in os.walk(movedir):
        for filename in files:
            if filename.endswith(extensions):
                yield os.path.join(root, filename)

def find_lines(fname, text):
    with open(fname) as fp:
         return [line for line in fp if text in line]

with open('final_file.txt', 'w') as f:
    for fname in find_files(movedir, 'root.vrpj', 'root.vprj'):
        f.writelines(find_lines(fname, 'table'))

【讨论】:

  • 我正在尝试第一个版本。 final_file.txt 是空的。
  • 那么你绝对应该尝试第二个版本,因为你不想要 8 级缩进的原因之一是它很难调试。对于 v2,您可以检查 list(find_files(...)) 是否返回您期望的文件,如果 find_lines(fname, 'table') - 在 fname 上,您知道有一行包含 "table" - 返回包含该/那些行的列表。
【解决方案3】:

我终于解决了

    import os

rootdir = my root folder

# creates a file f that contains all the lines of the files 
# with "root.vrpj" or "root.vprj" in their name
# and who are inside "App_integrations" folders
# without duplicates

#creating the big file with all the file containing the lines I need
f = open('final_file.txt', 'a')
for root, dirs, files in os.walk(rootdir):  
    for filename in files:
        if (filename.endswith(("root.vrpj", "root.vprj")) and ("App_Integration" in os.path.join(root, filename))):
            full_name = os.path.join(root, filename) 
            data = open(full_name).read()
            f.write(data + "\n")                 
f.close()

#copying the lines I need to f1 without duplicates
lines_seen = set()
f = open('final_file.txt')
f1 = open('testread1.txt', 'a')
doIHaveToCopyTheLine=False
for line in f.readlines():
    if (("Table" in line) and (line not in lines_seen)):
        doIHaveToCopyTheLine=True
        if doIHaveToCopyTheLine:
            f1.write(line)
            lines_seen.add(line)
f1.close()
f.close()

【讨论】:

    【解决方案4】:

    查找文件

    from pathlib import Path
    import itertools
    
    source_dir = Path(<source_dir>)
    
    patterns = ['**/*root.vrpj', '**/*root.vprj']
    
    files = itertools.chain.from_iterables(source_dir.glob(pat) for pat in patterns)) 
    

    过滤文件:

    def filter_lines(files):
        for file in files:
            if not 'App_Integration' in file.parts:
                continue
            with file.open('r') as file_handle:
                for line in file_handle:
                    if 'table' in line:
                        yield line
    

    写输出

    def save_lines(lines, output_file=sys.std_out):
        for line in lines:
            output_file.write(line)
    
    with Path(<output_file>).open('w') as output_file:
        save_lines(filter_lines(files), as output_file)
    

    【讨论】:

      猜你喜欢
      • 2014-01-26
      • 2017-11-18
      • 2012-02-15
      • 1970-01-01
      • 2013-06-01
      • 2020-06-22
      • 2014-08-12
      • 2013-10-24
      相关资源
      最近更新 更多