tags:

views:

77

answers:

1

World's most convuluted title I know, an example should explain it better. I have a large txt file in the below format, though details and amount of lines will change everytime:

Username: john_joe                    Owner:  John Joe
Account:  
CLI:      
Default:  
LGICMD:   
Flags: 
Primary days:
Secondary days: 
No access restrictions
Expiration: 
Pwdlifetime:
Last Login: 
Maxjobs:    
Maxacctjobs:
Maxdetach:  
Prclm:      
Prio:       
Queprio: 
CPU:     
Authorized Privileges: 
  BYPASS
Default Privileges: 
  SYSPRV

This sequence is repeated a couple of thousand times for different users. I need to find every user (ideally the entire first line of the above) that has SYSPRV under "Default Permissions". I know I could write an application to do this, I was just hoping their might be a nice regex I could use.

Cheers

+3  A: 
^Username:\s*(\S+)((?!^Username).)*Default Privileges:\s+SYSPRV

with the option to make ^ match start of line, and to make dot match newlines, will isolate those records and capture the username in backreference no. 1. Tell me which language you're using, and I'll provide a code sample.

Explanation:

^Username:\s: match "Username" at the start of the line, a colon and any whitespace.

(\S)+": match any non-whitespace characters and capture them into backreference no. 1. This will be the Username.

((?!Username).)*: Match any character as long as it's not the "U" of "Username". This ensures that we won't accidentally cross over into the next record.

Default Privileges:\s+SYSPRV: match the required text.

So in Python, for example, you would use:

result = re.findall(r"(?sm)^Username:\s*(\S+)((?!^Username).)*Default Privileges:\s+SYSPRV", subject)
Tim Pietzcker
+1 Good answer. More robust for the negative assertion would be this: `(?!^Username:)`.
FM
Thanks for the quick reply Tim. I was hoping to do this with grep, is that possible? Thanks.
Hinchy
I'm not sure - don't know the Unix toolset well enough. I think the original grep doesn't support lookahead (which this regex uses), and is line-based, so you can't match things over several lines. But I may be completely wrong about that.
Tim Pietzcker
@FM: Good point. Have edited my answer accordingly.
Tim Pietzcker