Python/FAQ/Директории

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
· Python ·

Содержание

Введение

#-----------------------------
entry = os.stat("/usr/bin/vi")
#-----------------------------
entry = os.stat("/usr/bin")
 
#-----------------------------
entry = os.stat(INFILE.name)
#-----------------------------
entry = os.stat("/usr/bin/vi")
ctime = entry.st_ino
size = entry.st_size
#-----------------------------
f = open(filename)
 
f.seek(0, 2)
if not f.tell():
    raise SystemExit("%s doesn't have text in it."%filename)
 
#-----------------------------
 
for filename in os.listdir("/usr/bin"):
    print "Inside /usr/bin is something called", filename
#-----------------------------

Получение и установка меток даты/времени

#-----------------------------
fstat = os.stat(filename)
readtime = fstat.st_atime
writetime = fstat.st_mtime
 
os.utime(filename, (newreadtime, newwritetime))
 
#DON'T DO THIS:
readtime, writetime = os.stat(filename)[7:9]
#-----------------------------
SECONDS_PER_DAY = 60 * 60 * 24
fstat = os.stat(filename)
atime = fstat.st_atime - 7 * SECONDS_PER_DAY
mtime = fstat.st_mtime - 7 * SECONDS_PER_DAY
 
os.utime(filename, (atime, mtime))     
#-----------------------------
mtime = os.stat(filename).st_mtime
utime(filename, (time.time(), mtime))
#-----------------------------
#!/usr/bin/perl -w
 
# uvi - vi a file without changing its access times
 
import sys, os
if len(sys.argv) != 2:
    raise SystemExit("usage: uvi filename")
filename = argv[1]
fstat = os.stat(filename)
# WARNING: potential security risk
 
os.system( (os.environ.get("EDITOR") or "vi") + " " + filename)
os.utime(filename, (fstat.st_atime, fstat.st_mtime))
#-----------------------------

Удаление файла

#-----------------------------
os.remove(filename)
 
err_flg = 0
for filename in filenames:
    try:
 
        os.remove(filename)
    except OSError, err:
        err_flg = 1
if err_flg:
    raise OSError("Couldn't remove all of %s: %s" % (filenames, err))
#-----------------------------
 
os.remove(filename)
#-----------------------------
success = 0
for filename in filenames:
    try:
        os.remove(filename)
        success += 1
    except OSError, err:
        pass
 
if success != len(filenames):
    sys.stderr.write("could only delete %d of %d files" % \
                     (success, len(filenames)))
 
#-----------------------------

Копирование или перемещение файла

#-----------------------------
import shutil
shutil.copy(oldfile, newfile)
 
#-----------------------------
## NOTE: this doesn't do the same thing as the Perl code,
## eg, handling of partial writes.
infile = open(oldfile)
outfile = open(newfile, "w")
 
blksize = 16384          # preferred block size?
 
while True:
    buf = infile.read(blksize)
    if not buf:
        break
 
    outfile.write(buf)
 
infile.close()
outfile.close()
#-----------------------------
# WARNING: these are insecure - do not use in hostile environments
os.system("cp %s %s" % (oldfile, newfile))       # unix
os.system("copy %s %s" % (oldfile, newfile))     # dos, vms
 
#-----------------------------
import shutil
 
shutil.copy("datafile.dat", "datafile.bak")
 
shutil.copy("datafile.new", "datafile.dat")
os.remove("datafile.new")
 
#-----------------------------

Recognizing Two Names for the Same File

#-----------------------------
import os
seen = {}
 
def do_my_thing(filename):
    fstat = os.stat(filename)
    key = (fstat.st_ino, fstat.st_dev)
    if not seen.get(key):
        # do something with filename because we haven't
 
        # seen it before
        pass
    seen[key] = seen.get(key, 0 ) + 1
 
#-----------------------------
for filename in files:
    fstat = os.stat(filename)
    key = (fstat.st_ino, fstat.st_dev)
    seen.setdefault(key, []).append(filename)
 
keys = seen.keys()
keys.sort()
for inodev in keys:
    ino, dev = inodev
    filenames = seen[inodev]
    if len(filenames) > 1:
        # 'filenames' is a list of filenames for the same file
 
        pass
#-----------------------------

Обработка всех файлов в директории

#-----------------------------
for filename in os.listdir(dirname):
    # do something with "$dirname/$file"
    pass
 
#-----------------------------
# XXX No -T equivalent in Python
#-----------------------------
# 'readir' always skipes '.' and '..' on OSes where those are
# standard directory names
for filename in os.listdir(dirname):
    pass
 
#-----------------------------
# XX Not Implemented -- need to know what DirHandle does
# use DirHandle;
 
#-----------------------------

Универсализация файловых имен, или получение списка имен соответствующих шаблону

#-----------------------------
import glob
filenames = glob.glob("*.c")
 
#-----------------------------
filenames = [filename for filename in os.listdir(path) if filename.endswith(".c")] 
#-----------------------------
import re
allowed_name = re.compile(r"\.[ch]$", re.I).search
filenames = [f for f in os.listdir(path) if allowed_name(f)]
 
#-----------------------------
import re, os
allowed_name = re.compile(r"\.[ch]$", re.I).search
 
fnames = [os.path.join(dirname, fname) 
              for fname in os.listdir(dirname)
              if allowed_name(fname)]
#-----------------------------
 
dirs = [os.path.join(path, f)
            for f in os.listdir(path) if f.isdigit()]
dirs = [d for d in dirs if os.path.isdir(d)]
dirs = sorted(dirs, key=int)    # Sort by numeric value - "9" before "11"
 
#-----------------------------

Рекурсивная обработка всех файлов в директории

# Processing All Files in a Directory Recursively
 
# os.walk is new in 2.3.
 
# For pre-2.3 code, there is os.path.walk, which is
# little harder to use.
 
#-----------------------------
import os
 
for root, dirs, files in os.walk(top):
    pass # do whatever
 
#-----------------------------
import os, os.path
for root, dirs, files in os.walk(top):
    for name in dirs:
        print os.path.join(root, name) + '/'
 
    for name in files:
        print os.path.join(root, name)
 
#-----------------------------
import os, os.path
numbytes = 0
for root, dirs, files in os.walk(top):
    for name in files:
        path = os.path.join(root, name)
        numbytes += os.path.getsize(path)
 
print "%s contains %s bytes" % (top, numbytes)
 
#-----------------------------
import os, os.path
saved_size, saved_name = -1, ''
for root, dirs, files in os.walk(top):
    for name in files:
        path = os.path.join(root, name)
        size = os.path.getsize(path)
        if size > saved_size:
            saved_size = size
            saved_name = path
 
print "Biggest file %s in %s is %s bytes long" % (
    saved_name, top, saved_size)
 
#-----------------------------
import os, os.path, time
saved_age, saved_name = None, ''
for root, dirs, files in os.walk(top):
    for name in files:
        path = os.path.join(root, name)
        age = os.path.getmtime(path)
        if saved_age is None or age > saved_age:
            saved_age = age
            saved_name = path
 
print "%s %s" % (saved_name, time.ctime(saved_age))
 
#-----------------------------
#!/usr/bin/env python
# fdirs - find all directories
import sys, os, os.path
argv = sys.argv[1:] or ['.']
 
for top in argv:
    for root, dirs, files in os.walk(top):
        for name in dirs:
            path = os.path.join(root, name)
            print path

Удаление директории и её содержимого

#-----------------------------
 
# DeleteDir - remove whole directory trees like rm -r
import shutil
shutil.rmtree(path)
 
# DON'T DO THIS:
import os, sys
def DeleteDir(dir):
    for name in os.listdir(dir):
        file = os.path.join(dir, name)
        if not os.path.islink(file) and os.path.isdir(file):
            DeleteDir(file)
        else:
 
            os.remove(file)
    os.rmdir(dir)

Переименование файлов

# Renaming Files
 
# code sample one to one from my perlcookbook
# looks strange to me.
import os
for fname in fnames:
    newname = fname
    # change the file's name
 
    try:
        os.rename(fname, newname)
    except OSError, err:
        print "Couldn't rename %s to %s: %s!" % \
                (fname, newfile, err)
 
# use os.renames if newname needs directory creation.
 
 
#A vaguely Pythonic solution is:
import glob
def rename(files, transfunc)
    for fname in fnames:
        newname = transfunc(fname)
        try:
 
            os.rename(fname, newname)
        except OSError, err:
            print "Couldn't rename %s to %s: %s!" % \
                  (fname, newfile, err)
 
def transfunc(fname): 
    return fname[:-5]
rename(glob.glob("*.orig"), transfunc) 
 
 
def transfunc(fname): 
    return fname.lower()
rename([f for f in glob.glob("*") if not f.startswith("Make)], transfunc) 
 
def transfunc(fname): 
    return fname + ".bad"
rename(glob.glob("*.f"), transfunc) 
 
def transfunc(fname): 
    answer = raw_input(fname + ": ")
    if answer.upper().startswith("Y"):
        return fname.replace("foo", "bar")
rename(glob.glob("*"), transfunc) 
 
def transfunc(fname):
    return ".#" + fname[:-1]
 
rename(glob.glob("/tmp/*~"), transfunc) 
 
# This _could_ be made to eval code taken directly from the command line, 
# but it would be fragile
#-----------------------------

Разделение имени файла на его составные части

#-----------------------------
import os
 
base = os.path.basename(path)
dirname = os.path.dirname(path)
dirname, filename = os.path.split(path)
base, ext = os.path.splitext(filename)
 
#-----------------------------
 
path = '/usr/lib/libc.a'
filename = os.path.basename(path)
dirname = os.path.dirname(path)
 
print "dir is %s, file is %s" % (dirname, filename)
# dir is /usr/lib, file is libc.a
#-----------------------------
path = '/usr/lib/libc.a'
dirname, filename = os.path.split(path)
name, ext = os.path.splitext(filename)
 
 
print "dir is %s, name is %s, extension is %s" % (dirname, name, ext)
#   NOTE: The Python code prints
# dir is /usr/lib, name is libc, extension is .a
#   while the Perl code prints a '/' after the directory name
# dir is /usr/lib/, name is libc, extension is .a
#-----------------------------
import macpath
path = "Hard%20Drive:System%20Folder:README.txt"
 
dirname, base = macpath.split(path)
name, ext = macpath.splitext(base)
 
print "dir is %s, name is %s, extension is %s" % (dirname, name, ext)
# dir is Hard%20Drive:System%20Folder, name is README, extension is .txt
#-----------------------------
# DON'T DO THIS - it's not portable.
def extension(path):
    pos = path.find(".")
    if pos == -1:
        return ""
 
    ext = path[pos+1:]
    if "/" in ext:
        # wasn't passed a basename -- this is of the form 'x.y/z'
        return ""
    return ext
 
#-----------------------------

Программа: symirror

#!/usr/bin/python
# sysmirror - build spectral forest of symlinks
import sys, os, os.path
 
pgmname = sys.argv[0]
if len(sys.argv)!=3:
    print "usage: %s realdir mirrordir" % pgmname
    raise SystemExit
 
(srcdir, dstdir) = sys.argv[1:3]
if not os.path.isdir(srcdir):
    print "%s: %s is not a directory" % (pgmname,srcdir)
    raise SystemExit
if not os.path.isdir(dstdir):
    try:
 
        os.mkdir(dstdir)
    except OSError:
        print "%s: can't make directory %s" % (pgmname,dstdir)
          raise SystemExit
 
# fix relative paths
 
srcdir = os.path.abspath(srcdir)
dstdir = os.path.abspath(dstdir)
 
def wanted(arg, dirname, names):
    for direntry in names:
        relname = "%s/%s" % (dirname, direntry)
        if os.path.isdir(relname):
            mode = os.stat(relname).st_mode
            try:
 
                os.mkdir("%s/%s" % (dstdir,relname), mode)
            except:
                print "can't mkdir %s/%s" % (dstdir,relname)
                raise SystemExit
 
        else:
            if relname[:2] == "./":
                relname = relname[2:]
            os.symlink("%s/%s" % (srcdir, relname), "%s/%s" % (dstdir,relname))
 
os.chdir(srcdir)
os.path.walk(".",wanted,None)

Программа: lst

# @@INCOMPLETE@@
 
# @@INCOMPLETE@@