python glob.glob - how to find a specific file (or a list of files) without knowing how deep it in in subdirs?
glob, linux, networking, python
Solution
Have you checked out os.walk()?
import os
for root, dirs, names in os.walk(path):
...
http://docs.python.org/library/os.html#os.walk
From the above link, here is a way to skip over certain directories:
import os
from os.path import join, getsize
for root, dirs, files in os.walk('python/Lib/email'):
print root, "consumes",
print sum(getsize(join(root, name)) for name in files),
print "bytes in", len(files), "non-directory files"
if 'CVS' in dirs:
dirs.remove('CVS') # don't visit CVS directories
Problem
Right now, I use subprocess to invocate `find` which does the job fine, but I am after a pythonic way of doing things. here's the current code: ``` cmd = "find /sys/devices/pci* | grep '/net/' |grep address" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) ``` In the output I receive the following list: ``` [root@host1 ~]# find /sys/devices/pci* |grep '/net/'|grep 'address' /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.0/net/eth0/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:01.0/0000:09:00.0/net/eth1/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:02.0/0000:0a:00.0/net/rename4/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:03.0/0000:0b:00.0/net/eth3/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:04.0/0000:0c:00.0/net/eth4/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:05.0/0000:0d:00.0/net/eth5/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:06.0/0000:0e:00.0/net/eth6/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:07.0/0000:0f:00.0/net/eth7/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:08.0/0000:10:00.0/net/eth8/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:09.0/0000:11:00.0/net/eth9/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:0a.0/0000:12:00.0/net/eth10/address /sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:0b.0/0000:13:00.0/net/eth11/address ``` Now, if I do `glob.glob('/sys/devices/pci*/*/*/*/*/*/*/net/')` I do get a list of directories, and I can even look for the files, but it definitely seems to take longer than `find` does, even through subprocess. Moreover, the set of results is huge, and I can't know ahead whether the specific hosts' architecture will have the same directory structure, so I don't know how many asterisks to enter in `glob.glob()`. My question is, how can I repeat the behaviour the simple `find | grep` command achieves, or, alternatively, if there is a nicer way of finding all the MACs of all the NICs a host has, whether active or not (I'm looking for specific MAC patterns here) EDIT: Shouldn't have used glob, os.walk seems to be doing the job: ``` >>> for root, dirs, names in os.walk('/sys/devices/'): ... if 'address' in names and 'pci' in root: ... f = open(str(root + '/address'), 'r') ... mac = f.readlines()[0].strip() ... f.close() ... print mac ... eth = root.split('/')[-1] ... print eth ```