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.

Supposing I have something like the following, a typical business PC situation:

drwxr-xr-x 1 whatever whoever       3 Oct  3 16:40 invoices2009
drwxr-xr-x 1 whatever whoever       4 Oct  3 16:40 invoices2010
drwxr-xr-x 1 whatever whoever       2 Oct  3 16:40 invoices2011
-rwxr-xr-x 1 whatever whoever  440575 Oct  3 16:40 tax2010_1
-rwxr-xr-x 1 whatever whoever  461762 Oct  3 16:40 tax2010_2
-rwxr-xr-x 1 whatever whoever  609123 Oct  3 16:40 tax2010_3

Now let's be lazy and just type:

$ ls -l *2010*

Supposing that there is something in the invoices2010 directory, it won't work as expected. Since the directory name contains the 2010 year as well, ls will also list the files in invoices2010, although I only want to list those in the current directory. Even funnier: imagine the tax2010* files weren't there at all and there were not those three directories as in the example, but 50 of them. Yes I've tried it out: ls will not even indicate which files are in which directory, but simply list them top-down, just as if all files resided in the current directory (unless you explicitly specify the -R option, certainly I do know that)

Plus, I know that I can do this with find, too, but is there also any way to accomplish this task with a plain ls one-liner (which, obviously, has a far less complicated syntax)?

share|improve this question
    
What shell is it? Bash? –  warl0ck Oct 7 '12 at 6:03

6 Answers 6

up vote 5 down vote accepted

Looks like your question is "How to list files by pattern excluding directories with ls only".

There is no way to do it with pure ls. You can combine ls + grep like:

ls -ld *2010* | grep -v '^d'

However it's much better to use find for that:

find . -maxdepth 1 -type f -name "*2010*"
share|improve this answer
    
Ah! I should have thought about greping for ^d. I didn't think of that, obviously. Thank you. –  syntaxerror Oct 5 '12 at 16:09

ls -dlp *2010* would be a good start to the solution, but it depends what you want the output to look like.

share|improve this answer
    
No, it would not be a good start at all. In my example, I wish to have the tax* files listed, whilst your solution would simply list all directories that match the pattern without showing their file content. That's something completely different. –  syntaxerror Oct 5 '12 at 7:47
1  
I'm not really sure what you want the output to look like. You said you only want files in the current directory to be listed. Try also ls -ldp *2010 –  Julian Oct 5 '12 at 7:51
    
@syntaxerror - I don't understand your question either. You did ask for 'only files in the current directory', which is what this answer does. But your comment appears to want the inverse? All files in all sub-directories? Can you edit your question to be clearer? –  ire_and_curses Oct 5 '12 at 7:53
    
There is actually nothing much to "edit". So again: I want the tax* files in the current directory to be listed, but the directory "invoices2010" which resides in the same working directory and which also matches the given *2010* wildcard pattern should be skipped in the listing. –  syntaxerror Oct 5 '12 at 8:03

It's not possible to selectively filter out directories using only ls. You need either find or ls | grep, as described in rush's answer . But for your specific example, to answer the question you asked in your comment:

So again: I want the tax* files in the current directory to be listed, but the directory "invoices2010" which resides in the same working directory and which also matches the given 2010 wildcard pattern should be skipped in the listing.

you can do

ls -l --ignore='invoices*' *tax2010*

which filters out anything matching the ignore shell pattern.

share|improve this answer
    
Thanks. That's better than nothing, in any case. –  syntaxerror Oct 5 '12 at 16:07

Use zsh…

ls -l *2012*(.)

The glob qualifier . means regular files only.

share|improve this answer

Don't use grep with ls,

In bash you could show files that have a "2010" in its name but not staring with a number:

ls -l *[!0-9]2010*

share|improve this answer

There are reasons not to grep against ls but if you disregard them, this works. Use the ls command as an input array, call ls -ld on each entry piped to grep to exclude directories with the output sent to null, and if successful echo the original input:

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

You can invert the grep and conditional output, same results:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

EDIT: My bad, this works without a pattern match, but if you add a wildcard search as in the OP above, and you have a directory that matches the pattern, the output still includes system messages so you would need to filter further to get just the file list.

EDIT again: fixed backslashes on /dev/null.

share|improve this answer
    
\dev\null?!?! –  manatwork Oct 7 '13 at 9:20
    
Thanks fixed that. –  Don R Oct 7 '13 at 9:24

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.