目录
目录遍历
首先我们来看如何实现目录遍历
目录遍历的过程很简单:
- 将目标路径作为当前目录
- 罗列出当前目录下的所有内容
- 判断每一个目标是否是文件夹。
- 如果是,进入该文件夹搜索(将文件夹路径改为当前路径,多级目录在此处会循环)
为什么我们要使用递归,与for对已知大小的列表的遍历相比,递归更适合与那些确定开始结束条件而过程不确定的情况。我们将初始路径设为起点,将目录下没有其他目录可以进入的情况设为终点
让我们来看如何通过递归的方式来遍历某个路径下的所有内容
def search(path):
content = os.listdir(path)
for each in content:
each_path = path + os.sep + each
if os.path.isdir(each_path):
search(each_path)
print(each_path)#测试输出
- 第1行:首先我们先定义一个search函数,参数path是接收的路径
- 第2行:os.listdir(path) 将path路径下的所有(文件/文件夹)作为一个列表返回
- 第3行:使用for循环遍历当前目录
- 第4行:构建当前目录下文件的完整目录(当前目录/文件名称),os.sep为当前操作系统的分隔符
- 第5行:判断这个目标是否是文件夹
- 第6行:如果是,把这个文件夹作为新的路径像刚才那样再来一遍
- 第7行:最后在循环的后面我们加一个print来看看输出了什么
来看我们的测试目录test的结构
test
├── a
│ ├── a
│ ├── b
│ └── c
│ └── file.md
├── b
│ ├── a
│ └── b
│ └── target.py
├── c
│ └── a
└── d
测试,进入test目录并使用os.getcwd()返回当前路径:
>>> search(os.getcwd())
输出结果
/home/Jkob/Github/test/b/b/target.py
/home/Jkob/Github/test/b/b
/home/Jkob/Github/test/b/a
/home/Jkob/Github/test/b
/home/Jkob/Github/test/a/b
/home/Jkob/Github/test/a/a
/home/Jkob/Github/test/a/c/file.md
/home/Jkob/Github/test/a/c
/home/Jkob/Github/test/a
/home/Jkob/Github/test/d
/home/Jkob/Github/test/c/a
/home/Jkob/Github/test/c
目录的遍历有什么用呢,我们可以添加条件来(搜索/操作)目录下所有符合条件的文件
文件名搜索
我们来对刚刚的函数进行简单的修改
def search(path,keyword):
content= os.listdir(path)
for each in content:
each_path = path+os.sep+each
if filename in each:
print(each_path)
if os.path.isdir(each_path):
search(each_path,keyword)
与刚刚不同的只有简单几行
- 第1行:函数参数增加了要搜索的文件名
- 第5,6行:增加了判断,我们这里使用‘in’ 而不是‘==’ 的目的是为了使用模糊匹配,只要包含搜索的关键字就符合条件
-第8行:由于我们整个函数没有修改filename,所以我们可以将搜索条件传递下去
我们这次再来测试,寻找藏起来的target.py
>>>search(os.getcwd(),'target')
结果
/home/Jkob/Github/test/b/b/target.py
再试一次
>>>search(os.getcwd(),'tar')
结果
/home/Jkob/Github/test/b/b/target.py
文件内容搜索
然而只有文件名字符合并不能满足我们的需求,我们有时也需要查找文件里面的内容是否符合关键字需求
def content_search(filepath,keyword):
f = open(filepath,'r')
for line in f:
if keyword in line:
f.close()
return True
f.close()
return False
在这里我们定义了一个函数content_search(),搜索文件内容并默认返回False,如果符合关键字条件即返回True并终端该项搜索
别忘记关闭文件哦
接下来我们将这个函数整合到我们刚刚的文件搜索函数中
关键字搜索整合
我们来把刚才的内容搜索函数添加到我们刚才的搜索函数中
def search(path,keyword):
content= os.listdir(path)
for each in content:
each_path = path+os.sep+each
if keyword in each:
print(each_path)
if os.path.isdir(each_path):
search(each_path,keyword)
elif content_search(each_path,keyword):
print(each_path)
我们只添加了最后两行,即当该文件包含关键字时,我们显示该文件路径。但是为什么我们不能把这个和刚才文件名判定条件放在一起呢?因为有的文件名指代的是文件夹,我们需要将其放在文件夹判断之后
我们来测试一下,其实目录下的file.md文件是编辑过的,内容为’target’:
search(os.getcwd(),'tar')
返回
/home/Jkob/Github/test/b/b/target.py
/home/Jkob/Github/test/a/c/file.md
如果我们将整个文件作为工具的话,我们可以最后一行添加
search(os.getcwd(),input('Your Keyword:'))
完整代码
import os
def search(path,keyword):
content= os.listdir(path)
for each in content:
each_path = path+os.sep+each
if keyword in each:
print(each_path)
if os.path.isdir(each_path):
search(each_path,keyword)
elif content_search(each_path,keyword):
print(each_path)
def content_search(filepath,keyword):
f = open(filepath,'r')
for line in f:
if keyword in line:
f.close()
return True
f.close()
return False
search(os.getcwd(),input('Your Keyword:'))
示例:
[Jkob@localhost test] $ python3 test.py
Your Keyword:tar
/home/Jkob/Github/test/b/b/target.py
/home/Jkob/Github/test/a/c/file.md