Python:在当前目录中搜索文件及其所有父文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37427683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 19:23:18  来源:igfitidea点击:

Python: search for a file in current directory and all it's parents

pythonpython-3.xpython-2.7

提问by gaganso

Is there an inbuilt module to search for a file in the current directory, as well as all the super-directories?

是否有内置模块来搜索当前目录以及所有超级目录中的文件?

Without the module, I'll have to list all the files in the current directory, search for the file in question, and recursively move up if the file isn't present. Is there an easier way to do this?

如果没有该模块,我将不得不列出当前目录中的所有文件,搜索有问题的文件,如果文件不存在,则递归向上移动。有没有更简单的方法来做到这一点?

采纳答案by Harwee

Well this is not so well implemented, but will work

嗯,这不是很好实施,但会起作用

use listdirto get list of files/folders in current directory and then in the list search for you file.

用于listdir获取当前目录中的文件/文件夹列表,然后在列表中搜索您的文件。

If it exists loop breaks but if it doesn't it goes to parent directory using os.path.dirnameand listdir.

如果存在循环中断,但如果不存在,则使用os.path.dirnameand转到父目录listdir

if cur_dir == '/'the parent dir for "/"is returned as "/"so if cur_dir == parent_dirit breaks the loop

如果cur_dir == '/'父目录"/"的形式返回"/",所以如果cur_dir == parent_dir它打破了环

import os
import os.path

file_name = "test.txt" #file to be searched
cur_dir = os.getcwd() # Dir from where search starts can be replaced with any path

while True:
    file_list = os.listdir(cur_dir)
    parent_dir = os.path.dirname(cur_dir)
    if file_name in file_list:
        print "File Exists in: ", cur_dir
        break
    else:
        if cur_dir == parent_dir: #if dir is root dir
            print "File not found"
            break
        else:
            cur_dir = parent_dir

回答by sparrow

Here is an example that will find all the .csv files in a specified directory "path" and all its root directories and print them:

这是一个示例,它将查找指定目录“路径”及其所有根目录中的所有 .csv 文件并打印它们:

    import os
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(".csv"):
                path_file = os.path.join(root,file)
                print(path_file)

If you want to start at one directory and work your way through the parents then this would work for finding all the .csv files (for example):

如果您想从一个目录开始并通过父目录工作,那么这将适用于查找所有 .csv 文件(例如):

import os
import glob
last_dir = ''
dir = r'c:\temp\starting_dir'

os.chdir(dir)
while last_dir != dir:
    dir = os.getcwd()
    print(glob.glob('*.csv'))
    os.chdir('..')
    last_dir = os.getcwd()   

回答by fatal_error

The parent question was to walk parentdirectories (not descend into children like the findcommand):

父问题是遍历目录(而不是像find命令那样进入子目录):

# walk PARENT directories looking for `filename`:

f = 'filename'
d = os.getcwd()

while d != "/" and f not in os.listdir(d):
    d = os.path.abspath(d + "/../")

if os.path.isfile(os.path.join(d,f)):
    do_something(f)

Here's a version that uses shell globbing to match multiple files:

这是一个使用 shell globbing 匹配多个文件的版本:

# walk PARENT directories looking for any *.csv files,
# stopping when a directory that contains any:

f = '*.csv'
d = os.getcwd()

while d != "/" and not glob.glob(os.path.join(d, f)):
    d = os.path.abspath(d + "/../")

files = glob.glob(os.path.join(d,f))

for filename in files:
    do_something(filename)

回答by Roland Puntaier

Here a function that does an upward search:

这是一个向上搜索的函数:

import sys, os, os.path
def up_dir(match,start=None):
    """
    Find a parent path producing a match on one of its entries.
    Without match an empty string is returned.

    :param match: a function returning a bool on a directory entry
    :param start: absolute path or None
    :return: directory with a match on one of its entries

    >>> up_dir(lambda x: False)
    ''

    """

    if start is None:
        start = os.getcwd()
    if any(match(x) for x in os.listdir(start)):
        return start
    parent = os.path.dirname(start)
    if start == parent:
        rootres = start.replace('\','/').strip('/').replace(':','')
        if len(rootres)==1 and sys.platform=='win32':
            rootres = ''
        return rootres
    return up_dir(match,start=parent)

回答by GaetaWoo

I was looking for this too, since os.walkis exactly the opposite of what I wanted. That searches subdirectories. I wanted to search backwards through parent directories until I hit the drive root.

我也在寻找这个,因为os.walk这与我想要的完全相反。搜索子目录。我想在父目录中向后搜索,直到找到驱动器根目录。

Bumming some inspiration from previous answers, below is what I am using. It doesn't require changing the working directory and it has a place for you to do something when you find a match. And you can change how the match is found. I'm using regex but a basic string compare would work fine too.

从以前的答案中获得一些灵感,下面是我正在使用的。它不需要更改工作目录,当您找到匹配项时,它有一个地方可以让您做一些事情。您可以更改匹配项的查找方式。我正在使用正则表达式,但基本的字符串比较也可以正常工作。

# Looking for a file with the string 'lowda' in it (like beltalowda or inyalowda)
import os
import re # only if you want to use regex

# Setup initial directories
starting_dir = 'C:\Users\AvasaralaC\Documents\Projects'
last_dir = ''
curr_dir = starting_dir
filename = ''

# Loop through parent directories until you hit the end or find a match
while last_dir != curr_dir:
    for item in os.listdir(curr_dir):
        if re.compile('.*lowda.*').search(item): # Here you can do your own comparison
            filename = (curr_dir + os.path.sep + item)
            break
    if filename:
        break
    last_dir = curr_dir
    curr_dir = os.path.abspath(curr_dir + os.path.sep + os.pardir)

Other comparisons you could do are item.lower().endswith('.txt')or some other string comparison.

您可以进行的其他比较是item.lower().endswith('.txt')或其他一些字符串比较。

回答by Kjeld Flarup

Just wrote this to find the "images" directory, note '/' is Linux style

刚刚写这个是为了找到“images”目录,注意'/'是Linux风格

dir = os.getcwd()
    while dir != '/' and not glob.glob( dir + '/images' ):
        dir = os.path.dirname(dir)