0

So I am pretty new to what I currently refer to as "advanced" RegEx, please pardon me, it's probably really easy for you guys but I need to be pointed in the right direction because right now I am struggling.

I have crawled the forums and websites, (including: http://www.grymoire.com/Unix/Sed.html) and I can't find what I am looking for or at least, the reverse so I then reverse that and get the stdout that I want.

The data (stdin) looks like this:

C:\Users\Maison\Documents\AutoCad_dir
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

And what I want to do is using RegEx, remove every line with 4 directories or more and the proceeding 10 lines (including the CR \r).

So what remains will look something like this:

C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

NOTE: The volume label (C:) is not constant, no data I am working with is absolute.

Of course in the actual data I possess, there are a lot more lines similar to the one I am trying to erase.

The best I have so far is:

 sed '/pattern/I,+11 d' infile

But I cannot come up with a logical pattern, every pattern I have come up with so far erases every line regardless of directory count.

I was reluctant to ask but this ultimately will allow me to understand RegEx & GNU sed better.

2

Example:

sed '/^[A-Z]:\\\([^\\]\+\\\)\{3,\}/,+10d' test.txt

If you would use extended regexps (specify -rto sed), then the expression would become a bit easier to read as you would only have to escape \:

sed -r '/^[A-Z]:\\([^\\]+\\){3,}/,+10d' test.txt

The notable part is ([^\\]+\\){3,}, the pattern in the parenthesis tells it to match 1 or more instances of any character except /, then followed by a single /. {3,} tells it that the pattern in the parenthesis must be matched at least 3 times for it to match.

1

Using awk (as the question was using the tag):

$ awk -F '\\' 'NF > 4 { skip = 11 } --skip < 0 { print }' file.in
C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D

This treats each line as a \-delimited record. If the number of fields in the record is greater than four, we skip this record and the next 10 lines of input by setting skip = 11. This variable is then decremented for each line of input, and if its value is negative (which means that we've skipped the lines we'd like to skip), we print the line.

The script may be shortened to

$ awk -F '\\' 'NF > 4 { skip = 11 } --skip < 0' file.in

Both versions of this script will fail (produce the wrong output) if any other line than the first of each block contains four \ or more.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.