glob
是python的标准库模块,只要安装python就可以使用该模块。glob模块主要用来查找目录
和文件
,可以使用*、?、[]
这三种通配符
对路径中的文件进行匹配。
*
:代表0个或多个字符?
:代表一个字符[]
:匹配指定范围内的字符,如[0-9]匹配数字Unix样式路径名模式扩展
>>> dir(glob)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__',
'__name__', '__package__', '__spec__', '_glob0', '_glob1', '_glob2', '_iglob',
'_ishidden', '_isrecursive', '_iterdir', '_rlistdir', 'escape', 'fnmatch',
'glob', 'glob0', 'glob1', 'has_magic', 'iglob', 'magic_check',
'magic_check_bytes', 'os', 're']
>>>
glob模块常用的两个方法有:glob.glob() 和 glob.iglob
,下面详细介绍
def glob(pathname, *, recursive=False):
"""Return a list of paths matching a pathname pattern.
The pattern may contain simple shell-style wildcards a la
fnmatch. However, unlike fnmatch, filenames starting with a
dot are special cases that are not matched by '*' and '?'
patterns.
If recursive is true, the pattern '**' will match any files and
zero or more directories and subdirectories.
"""
return list(iglob(pathname, recursive=recursive))
def glob(pathname, *, recursive=False):
pathname
:该参数是要匹配的路径recursive
:如果是true就会递归的去匹配符合的文件路径,默认是False返回匹配
到的路径列表
先给出测试使用的目录结构:
test_dir/
├── a1.txt
├── a2.txt
├── a3.py
├── sub_dir1
│ ├── b1.txt
│ ├── b2.py
│ └── b3.py
└── sub_dir2
├── c1.txt
├── c2.py
└── c3.txt
1、返回目录的路径列表
>>> path_list1 = glob.glob('./test_dir/')
>>> path_list
['./test_dir/']
2、匹配'./test_dir/*
路径下的所有目录和文件
,并返回路径列表
>>> path_list2 = glob.glob('./test_dir/*')
>>> path_list2
['./test_dir/a3.py', './test_dir/a2.txt', './test_dir/sub_dir1', './test_dir/sub_dir2', './test_dir/a1.txt']
3、匹配./test_dir/
路径下含有的所有.py文件
(不递归
)
>>> path_list3 = glob.glob('./test_dir/*.py')
>>> path_list3
['./test_dir/a3.py']
>>> path_list4 = glob.glob('./test_dir/*/*.py')
>>> path_list4
['./test_dir/sub_dir1/b2.py', './test_dir/sub_dir1/b3.py', './test_dir/sub_dir2/c2.py']
4、递归的
匹配./test_dir/**
路径下的所有目录和文件
,并返回路径列表
>>> path_list5 = glob.glob('./test_dir/**', recursive=True)
>>> path_list5
['./test_dir/', './test_dir/a3.py', './test_dir/a2.txt', './test_dir/sub_dir1', './test_dir/sub_dir1/b2.py', './test_dir/sub_dir1/b3.py', './test_dir/sub_dir1/b1.txt', './test_dir/sub_dir2', './test_dir/sub_dir2/c3.txt', './test_dir/sub_dir2/c1.txt', './test_dir/sub_dir2/c2.py', './test_dir/a1.txt']
>>> path_list6 = glob.glob('./test_dir/**/*.py', recursive=True)
>>> path_list6
['./test_dir/a3.py', './test_dir/sub_dir1/b2.py', './test_dir/sub_dir1/b3.py', './test_dir/sub_dir2/c2.py']
注意:
如果要对某个路径下进行递归,一定要在后面加两个*
>>> path_list = glob.glob('./test_dir/', recursive=True)
>>> path_list
['./test_dir/']
*、?、[]
实例>>> import glob
>>> glob.glob('./[0-9].*')
['./1.gif', './2.txt']
>>> glob.glob('*.gif')
['1.gif', 'card.gif']
>>> glob.glob('?.gif')
['1.gif']
>>> glob.glob('**/*.txt', recursive=True)
['2.txt', 'sub/3.txt']
>>> glob.glob('./**/', recursive=True)
['./', './sub/']
我们在使用python时时常会遇到调用某些文件的需求,这时我们就需要得到这些文件的路径。python强大的自带os模块使得获得路径变得很容易。下面介绍如何使用os.walk
函数来遍历文件夹及子文件夹下所有文件并得到路径。
os.walk
的完整定义形式如下:
os.walk(top, topdown=True, onerror=None, followlinks=False)
参数:
以上四个参数一般只需要指定第一个文件夹路径,剩下的一般情况不需要指定。
os.walk
使用os.walk 的返回值是一个生成器(generator),也就是说我们需要用循环不断的遍历它(不可以直接print
),来获得所有的内容。
每次遍历的对象都是返回的是一个三元元组(root,dirs,files)
注意,函数会自动改变
root
的值使得遍历所有的子文件夹。所以返回的三元元组的个数为所有子文件夹(包括子子文件夹,子子子文件夹等等)加上1(根文件夹)。
举例:
对于具有以下结构的目录进行测试:
$ cd namesort/
$ tree
.
|-- namelist.txt
|-- nameout.txt
|-- namesorttest.py
`-- test
|-- name2.txt
|-- namelist.txt
|-- nameout.txt
`-- namesort.py
执行:
import os
path = '/home/jhxie/Workspace/namesort'
for root,dirs,files in os.walk(path):
print root,dirs,files
输出为:
/home/jhxie/Workspace/namesort ['test'] ['nameout.txt', 'namelist.txt', 'namesorttest.py']
/home/jhxie/Workspace/namesort/test [] ['nameout.txt', 'name2.txt', 'namelist.txt', 'namesort.py']
os.path.join
使用)由于os.walk
获得的并不是路径,所以需要将其内容进行连接得到路径。
这时使用python自带函数os.path.join
,其语法为:
os.path.join(path1[, path2[, ...]])
其中嵌套的[]表示写在最前面的是高级目录,后面的是低级的,也就是按参数排列顺序拼接。
举例:
os.path.join("home", "me", "mywork")
在Linux系统上会返回home/me/mywork
在Windows系统上会返回home\me\mywork
可能大家已经注意到了,此函数并不是简单的字符串连接函数,你不需要在输入的参数字符串中加入分隔符,函数会根据你的系统自动加入对应的分隔符,这也是这个函数存在的意义所在。
所以我们正好使用os.path.join()
来处理上面生成的遍历结果:
import os
path = '/home/jhxie/Workspace/namesort'
for root,dirs,files in os.walk(path):
for file in files:
print(os.path.join(root,file))
输出结果:
/home/jhxie/Workspace/namesort/nameout.txt
/home/jhxie/Workspace/namesort/namelist.txt
/home/jhxie/Workspace/namesort/namesorttest.py
/home/jhxie/Workspace/namesort/test/nameout.txt
/home/jhxie/Workspace/namesort/test/name2.txt
/home/jhxie/Workspace/namesort/test/namelist.txt
/home/jhxie/Workspace/namesort/test/namesort.py
import os
import glob
train_txt_path = os.path.join("data", "LEDNUM", "train.txt")
train_dir = os.path.join("data", "LEDNUM", "train_data")
def gen_txt(train_txt_path, train_dir):
with open(train_txt_path, 'w') as f:
for img_path in glob.iglob(os.path.join(train_dir, '**/*.jpg'), recursive=True):
label = os.path.basename(img_path).split('_')[0]
line = img_path + ' ' + label + '\n'
f.write(line)
import os
train_txt_path = os.path.join("data", "LEDNUM", "train.txt")
train_dir = os.path.join("data", "LEDNUM", "train_data")
def gen_txt(train_txt_path, train_dir):
f = open(txt_path, 'w')
for root, s_dirs, _ in os.walk(img_dir, topdown=True): # 获取 train文件下各文件夹名称,
for sub_dir in s_dirs:
i_dir = os.path.join(root, sub_dir) # 获取各类的文件夹 绝对路径
img_list = os.listdir(i_dir) # 获取类别文件夹下所有png图片的路径
for i in range(len(img_list)):
if not img_list[i].endswith('jpg'): # 若不是png文件,跳过
continue
label = img_list[i].split('_')[0]
img_path = os.path.join(i_dir, img_list[i])
line = img_path + ' ' + label + '\n'
f.write(line)
f.close()