0

I'm trying to remove a key/value pair if the key contains 'empty' values.

I have tried the following dictionary comprehension and tried doing it in long form, but it doesn't seem to actually do anything and I get no errors.

def get_Otherfiles():
    regs = ["(.*)((U|u)ser(.*))(\s=\s\W\w+\W)", "(.*)((U|u)ser(.*))(\s=\s\w+)", "(.*)((P|p)ass(.*))\s=\s(\W(.*)\W)", "(.*)((P|p)ass(.*))(\s=\s\W\w+\W)"]
    combined = "(" + ")|(".join(regs) + ")"
    cred_results = []
    creds = []
    un_matched = []
    filesfound = []
    d = {}
    for root, dirs, files in os.walk(dir):
        for filename in files:
            if filename.endswith(('.bat', '.vbs', '.ps', '.txt')):
                readfile = open(os.path.join(root, filename), "r")
                d.setdefault(filename, [])
                for line in readfile:
                    m = re.match(combined, line)
                    if m:
                        d[filename].append(m.group(0).rstrip())
                    else:
                        pass
    result = d.copy()
    result.update((k, v) for k, v in d.iteritems() if v is not None)
    print result

Current output:

{'debug.txt': [], 'logonscript1.vbs': ['strUser = "guytom"', 'strPassword = "P@ssw0rd1"'], 'logonscript2.bat': ['strUsername = "guytom2"', 'strPass = "SECRETPASSWORD"']}

As you can see I have entries with empty values. I'd like to remove these before printing the data.

5
  • update will just leave the unwanted values in, don't you want result = dict((k, v) for k, v in d.iteritems() if v) (an empty list is not None)? Commented Sep 15, 2014 at 15:59
  • There are no None values in your output. What exactly are you trying to do? Commented Sep 15, 2014 at 16:01
  • Id like to remove the Keys with empty values. Im assuming the code Im using is looking for literal values of 'None'? Commented Sep 15, 2014 at 16:02
  • It seems like you want to filter if v is an empty string (so, just if v). Another way is to change the front of your regex from (.*) to (.+). Commented Sep 15, 2014 at 16:03
  • 3
    We have a lot of silent -1'ers here! Seems like a reasonable question to me. Commented Sep 15, 2014 at 16:07

3 Answers 3

1

In this part of your code:

            d.setdefault(filename, [])
            for line in readfile:
                m = re.match(combined, line)
                if m:
                    d[filename].append(m.group(0).rstrip())
                else:
                    pass

You always add filename as a key to the dictionary, even if you don't subsequently add anything to the resulting list. Try

            for line in read file:
                m = re.match(combined, line)
                if m:
                    d.setdefault(filename, []).append(m.group(0).rstrip())

which will only initialize d[filename] to an empty list if it is actually necessary to have something on which to call append.

Sign up to request clarification or add additional context in comments.

1 Comment

You sir! deserve a medal ^_^ I knew there had to be a simple solution I couldn't see. In fact I had no idea you could do it like that :). Thank you
0
result = dict((k, v) for k, v in d.iteritems() if v is not None)

update wont remove entries ... it will only add or change

a = {"1":2}
a.update({"2":7})
print a # contains both "1" and "2" keys

Comments

0

Looking at the first matching group in your regex, (.*), if the regex matches but there are no characters to match, group(0) is "", not None. So, you can filter there.

result.update((k, v) for k, v in d.iteritems() if not v)

But you can also have your regex do that part for you. Change that first group to (.+) and you won't have empty values to filter out.

EDIT

Instead of removing empty values at the end, you can avoid adding them to the dict altogether.

def get_Otherfiles():
    # fixes: make it a raw string so that \s works right and
    # tighten up filtering, ... (U|u) should probably be [Uu] ...
    regs = ["(.+)\s*((U|u)ser(.*))(\s=\s\W\w+\W)", "(.*)((U|u)ser(.*))(\s=\s\w+)", "(.*)((P|p)ass(.*))\s=\s(\W(.*)\W)", "(.*)((P|p)ass(.*))(\s=\s\W\w+\W)"]
    combined = "(" + ")|(".join(regs) + ")"
    cred_results = []
    creds = []
    un_matched = []
    filesfound = []
    d = {}
    for root, dirs, files in os.walk(dir):
        for filename in files:
            if filename.endswith(('.bat', '.vbs', '.ps', '.txt')):
                readfile = open(os.path.join(root, filename), "r")
                # assuming you want to aggregate matching file names...
                content_list = d.get(filename, [])
                content_orig_len = len(content_list)
                for line in readfile:
                    m = re.match(combined, line)
                    if m:
                        content_list.append(m.group(0))
                if len(content_list) > content_orig_len:
                    d[filename] = content_list

8 Comments

Although I couldn't see how changing my regx would resolve the issue (the regx is being used to search for items in the doc, the doc gets added to the dic if it is of a certain ext not if it matches regex). I gave it a try, but unfortunately I end up with the same result.
del((k) for k, v in d.iteritems() if v is "") something like this?
oops, I made a mistake in the post... it should have been if not v. No need compare against "", just anything that is "falsy" will do (and is a bit faster).
Nope still have blank values present. From what Ive seen from others so far the update wont remove the entry. Im struggling with this as I cant find out how to check if a value is empty. Ive tried the obvious "" but no luck :(
I think something along these lines will work del((k)(k, v) for k, v in d.iteritems() if not v) but I cant get the syntax correct
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.