Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

When I execute ls /directory | grep '[^term]' in Bash I get a regular listing, as if the grep command is ignored somehow. I tried the same thing with egrep, I tried to use it with double and single quotes, but to no better results. When I try ls /directory | grep '^[term] I get all entries beginning with term - as expected.

I have tried out this command in an online editor, where I can test my regex and it worked as it should. But not in Bash. So it works in a simulation, but not in real life.

I work on Crunchbang Linux 10. I hope this is enough information and am looking forward to every hint, because failing to execute on such a basic level and wasting hours of time is really frustrating!

share|improve this question
    
I am confused because of the negate in the title. Do you want to grep lines starting with term. Or do you want to grep for lines not containing term at all? –  Bernhard Mar 31 '13 at 20:21
    
@Bernhard: I want a listing without the term in the square brackets. It doesn't have to be 'term' exactly! As far as I understood it, [^abc] means that anything containing a, b or c or any combination of it should not be in the listing. –  erch Mar 31 '13 at 20:26

2 Answers 2

up vote 5 down vote accepted

Are you sure what you want is happening? When you run ls /directory | grep '[^term]' you are essentially grepping for not the letters t e r m. This means if a file has other letters in its name it will still appear in the output of ls. Take the following directory for instance:

$ ls
alpha  brave  bravo  charlie  delta

Now if I run ls |grep '^[brav]' I get the following:

$ ls |grep '^[brav]'
alpha
brave
bravo

As you can see, not only did I get brave and bravo I also got alpha because the character class [] will get any letter from that list.

Consequently, if I run ls |grep '[^brav]' I will get all the files that do not contain the characters b r a v anywhere in the name.

$ ls |grep '[^brav]'
alpha
bravo
brave
charlie
delta

If you notice it included the entire directory listing because all the files had at least one letter that was not included in the character class.

So as Kanvuanza said, to grep for the inverse of "term" as opposed to the characters t e r m you should do it using grep -v.

For instance:

$ ls |grep -v 'brav'
alpha
charlie
delta

Also if you don't want the files that have any characters in the class use grep -v '[term]'. That will keep any files from showing up that have any of those characters. (Kanvuanza's answer)

For instance:

$ ls |grep -v '[brav]'

As you can see there were no files listed because all the files in this directory included at least one letter from that class.

share|improve this answer
1  
This means if a file has other letters in its name it will still appear in the output of ls. This answers quite a few questions! :) So the best way for the moment seems to be the -v option. Thanks for your support! This question really ruined my afternoon, where your answer brightens my evening! –  erch Mar 31 '13 at 21:03

I guess that grep -v flag does what you want. From the man page:

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.

You can use ls /directory | grep -v [term] to print any non matching lines.

share|improve this answer
    
I am aware of this option, but am I wrong in assuming that [^xyz] is the opposite of [xyz] and should work in any case? I also want to avoid editing any settings anywhere on such a basic level. Using an inverting option and/or editing settings sure is a nice way around, but as far as I understood it, this should work without, out of the box. –  erch Mar 31 '13 at 20:29
    
I guess you're right, that is the common notation for class negation (ie. [^abc]. But I'm pretty sure that grep don't support class negations, except a few standard ones (eg. [[:^digits:]]). Grep support for negation is horrible! –  Kanvuanza Mar 31 '13 at 20:51
    
Grep support for negation is horrible! And this are the hints that are the real icing on the cake. I have the same issues with egrep and I'm far away from using [at least for me seemingly] more advanced commands at the moment. Can you suggest a command that provides better results and less headache? –  erch Mar 31 '13 at 21:09
    
@cellar.dweller, grep's handling of character classes is just fine. It just means something quite different than what you (mis)understand. [abc] means one of a, b, or c; [^abc] means anything but the above. It is one character. –  vonbrand Mar 31 '13 at 22:11
    
@cellar.dweller: I think your biggest issue is a misunderstanding of regex, specifically character classes within regex. –  tink Mar 31 '13 at 22:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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