is not a kind of basket
Join Date: May 2004
|
Hello all,
In light of the new forum.. I post a Python thread about directory content differences and sysadmin based work. Currently this script is used on the CLI and returns both common and unique directory contents (by name)... it could be used by a sysadmin to check for differences in backup directories, but it's not quite there yet. I'd like to put in a check for the date of last modification, and size... Also, might want to make it recursive to dive into subdirectories if the subdirectory is common. Anyhow, just sharing... if you have a chance, I've confirmed this works under "Linux > bash > python2.4" and "WinXP > command > python2.4", but I'd be interested to know if it fails on other platforms. (not that it should) And if you are a python freak like myself, and you see something that needs to be changed or maybe my coding practices aren't kosher... give a shout. No this is not a class project, so don't worry about doing 'my' homework... I've been learning python on my own, with the help of a friend. Code:
"""dirdiff.py: List common and uncommon files and subdirectories between
two given directories.
Usage: #python dirdiff.py [dir...] [dir...]
v0.0.1b --AppleNova edition--
Copyleft 2005 ;) use as you will...
"""
import sys
import os
#CLI interface#
if sys.argv[1] in ('-h', '--help', '/?'):
print __doc__
sys.exit(0)
if len(sys.argv)>3:
print "Input not understood, use '-h' for help."
sys.exit(0)
#Take care of full length directory names if not given#
if sys.argv[1].startswith('/'):
dirA = os.listdir(sys.argv[1])
else:
dirA = os.listdir(os.getcwd() + "//" + sys.argv[1])
if sys.argv[2].startswith('/'):
dirB = os.listdir(sys.argv[2])
else:
dirB = os.listdir(os.getcwd() + "//" + sys.argv[2])
#Define the comparing code#
def compareSame(listA, listB):
same = []
count = len(listA)
while count > 0:
if (listA[count-1] in listB) == True:
same.append(listA[count-1])
count = count -1
return same
def compareDiff(listA, listB):
diff = []
count = len(listA)
while count > 0:
if (listA[count-1] in listB) == False:
diff.append(listA[count-1])
count = count -1
return diff
#Prep for report#
same = compareSame(dirA, dirB)
diffA = compareDiff(dirA, dirB)
diffB = compareDiff(dirB, dirA)
#Print report#
print "#########--SAME in both directories--#########"
for i in same:
print "%s: is a common file" % (i,)
print '#########--Unique in "'+sys.argv[1]+'"--#########'
for i in diffA:
print "%s: is a unique file in directory %s" % (i, ('"'+sys.argv[1]+'"'))
print '#########--Unique in "'+sys.argv[2]+'"--#########'
for i in diffB:
print "%s: is a unique file in directory %s" % (i, ('"'+sys.argv[2]+'"')) no sig, how's that for being a rebel! |
quote |
Member
Join Date: Jul 2004
|
You may wish to look into using the built-in set type to make this easier.
For instance, finding unique elements in one of two lists can be quite easy. Code:
>>> a, b = set([1,2,3]), set([3,4, 1])
>>> a ^ b & a
set([2])
>>> b ^ a & b
set([4]) |
quote |
Student extraordinaire
Join Date: May 2004
Location: Canberra, Australia
|
Tiger's version of python doesn't work with sets, at least not for me. Works fine for me in SuSE 10.0.
Code:
NameError: name 'set' is not defined |
quote |
is not a kind of basket
Join Date: May 2004
|
Oh, this is odd... how would I turn a set, back into just a list?
I mean, aside from how I'm currently doing it that is: Code:
example = []
for i in set(var):
example.append(i) Is there something built into sets that can call just a list?no sig, how's that for being a rebel! |
quote |
Member
Join Date: Jul 2004
|
Code:
>>> list(set([1,2,3]))
[1, 2, 3] |
quote |
Member
Join Date: Jul 2004
|
But why do you need it as a list? You're likely overlooking some of Python's power.
|
quote |
is not a kind of basket
Join Date: May 2004
|
Sweet, so I replaced the compare code with this.
Code:
def cSame(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.intersection(listB))
def cDiff(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.difference(listB)) The reports now look a bit more 'formatted' too, I'll post the new script. |
quote |
is not a kind of basket
Join Date: May 2004
|
I wanted to just edit my parent post and replace the script there... but I'm not able to do so.
So I'll just chalk up another post in this thread. Code:
"""dirdiff.py: List common and uncommon files and subdirectories between
two given directories.
Usage: #python dirdiff.py [dir...] [dir...]
v0.0.2a --AppleNova edition--
Copyleft 2005 ;) use as you will...
"""
import sys
import os
#CLI interface#
if sys.argv[1] in ('-h', '--help', '/?'):
print __doc__
sys.exit(0)
if len(sys.argv)>3:
print "Input not understood, use '-h' for help."
sys.exit(0)
#Take care of full length directory names if not given#
if sys.argv[1].startswith('/'):
dirA = os.listdir(sys.argv[1])
else:
dirA = os.listdir(os.getcwd() + "//" + sys.argv[1])
if sys.argv[2].startswith('/'):
dirB = os.listdir(sys.argv[2])
else:
dirB = os.listdir(os.getcwd() + "//" + sys.argv[2])
#Define the comparing code#
def cSame(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.intersection(listB))
def cDiff(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.difference(listB))
#Misc. report prep#
def spaces(number):
string = ""
while number > 0:
string = string + " "
number = number -1
return string
#Print report#
print "#########--SAME in both directories--#########"
for i in cSame(dirA, dirB):
print "# %s %s --is a common file" % (i, spaces(20 - len(i)))
print '#########--Unique in "'+sys.argv[1]+'"--#########'
for i in cDiff(dirA, dirB):
print "# %s %s --is a unique file in directory %s"\
% (i, spaces(20 - len(i)), ('"'+sys.argv[1]+'"'))
print '#########--Unique in "'+sys.argv[2]+'"--#########'
for i in cDiff(dirB, dirA):
print "# %s %s --is a unique file in directory %s" \
% (i, spaces(20 - len(i)), ('"'+sys.argv[2]+'"')) You'll see the difference between the two scripts's output if you run it... no sig, how's that for being a rebel! |
quote |
Member
Join Date: Jul 2004
|
Code:
def spaces(number):
string = ""
while number > 0:
string = string + " "
number = number -1
return string Or perhaps you prefer:Code:
' ' * number |
quote |
Member
Join Date: Jul 2004
|
You may also wish to rewrite some of those functions to take advantage of generators.
Code:
def cSame(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.intersection(listB))
def cDiff(listA, listB):
listA, listB = set(listA), set(listB)
return list(listA.difference(listB)) Code:
def cSame(listA, listB):
listA, listB = set(listA), set(listB)
for x in listA & listB:
yield x
def cDiff(listA, listB):
listA, listB = set(listA), set(listB)
for x in listA ^ listB & listA:
yield x If you have directories with a huge number of files, using a generator can mean better memory efficiency that simply returning the entire list. |
quote |
Posting Rules | Navigation |
|
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Content Server for Plasma Screen | Bryson | Purchasing Advice | 0 | 2005-10-31 09:55 |
Python Failure after Tiger Upgrade | Caseyfern | Genius Bar | 0 | 2005-05-23 11:36 |
How Can You Reconstruct the File Directory After Disk Utility? | SilverGoat | Genius Bar | 0 | 2005-03-06 08:27 |