Tell me more ×
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.

I can use ls -ld */ to list all the directory entries in the current directory. Is there a similarly easy way to just list all the regular files in the current directory? I know I can use find

find . -maxdepth 1 -type f

or stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

but these do not strike me as being overly elegant. Is there a nice short way to list only the regular files (I don't care about devices, pipes, etc.) but not the sub-directories of the current directory? Listing symbolic links as well would be a plus, but is not a necessity.

share|improve this question
What do you mean by "overly elegant"? As far as I know, the find command is the best way to do what you want. For some reliable other options, you should look into shell specific commands (and those are anything but portable)! – rahmu Sep 18 '12 at 9:58
@rahmu I was for something similar to ls -d */, which is short, easy to type, and easy to understand. So I'm pretty happy with Ulrich Dangel's answer, even though I'm not using zsh. – daniel kullmann Sep 18 '12 at 10:41

3 Answers

up vote 3 down vote accepted

With zsh and Glob Qualifiers you can easily express it directly, e.g:

echo *(.)

will either only return the list of regular files or an error depending on your configuration.

For the non-directories:

echo *(^/)

(will include symlinks (including to directories), named pipes, devices, sockets, doors...)

echo *(-.)

for regular files and symlinks to regular files.

echo *(-^/)

for non-directories and no symlinks to directories either.

Also, see the D globbing qualifier if you want to include Dot files (hidden files), like *(D-.).

share|improve this answer
zsh surely has some real nice features. Maybe I should switch... – daniel kullmann Sep 18 '12 at 9:05
Obligatory zsh one-short-liner: … Ah, good, it's here already. – Gilles Sep 18 '12 at 23:43

The manual stated the 'f' option is against 'regular file' only, not pipes, socket or block/char devices, which means you're already doing the right stuff.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)
share|improve this answer

ls has no option to do that, but one of the nice things about unix & linux is that long-winded and inelegant pipelines can easily be turned into a shell script, function, or alias. and these can, in turn, be used in pipelines just like any other program.

(NOTE: there are some scope issues with functions and aliases. Scripts are available to any executable that can read and execute them. Aliases and functions are only available in the current shell - although a sub-shell's .profile/.bashrc etc may redefine them and thus make them available. Also, a script can be written in any language - including bash/sh, awk, perl, python, and others - whichever one is best for the job or that you are most familiar with)

e.g.

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

I've added xargs so that you can use use all the usual ls options, e.g. lsf -lrS

Because it uses find, all of the normally-hidden dotfiles will be displayed, and all of the filenames will be prefixed with ./ - that's about the only difference you'll notice.

You could exclude dot files with ! -iname '.*' but then you'd have to have two versions of the alias - one that displayed dot files and one that didn't.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Alternatively, if lsf was a script rather than an alias you could parse the options (perhaps with getopts or /usr/bin/getopt or similar), and exclude dotfiles unless -a was present.

share|improve this answer

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.