How to list only files and not directories of a directory Bash?
BashFile ListingBash Problem Overview
How can I list all the files of one folder but not their folders or subfiles. In other words: How can I list only the files?
Bash Solutions
Solution 1 - Bash
Using find
:
find . -maxdepth 1 -type f
Using the -maxdepth 1
option ensures that you only look in the current directory (or, if you replace the .
with some path, that directory). If you want a full recursive listing of all files in that and subdirectories, just remove that option.
Solution 2 - Bash
ls -p | grep -v /
ls -p lets you show / after the folder name, which acts as a tag for you to remove.
Solution 3 - Bash
-
carlpett's
find
-based answer (find . -maxdepth 1 -type f
) works in principle, but is not quite the same as usingls
: you get a potentially unsorted list of filenames all prefixed with./
, and you lose the ability to applyls
's many options;
alsofind
invariably finds hidden items too, whereasls
' behavior depends on the presence or absence of the-a
or-A
options.-
An improvement, suggested by Alex Hall in a comment on the question is to combine shell globbing with
find
:find * -maxdepth 0 -type f # find -L * ... includes symlinks to files
- However, while this addresses the prefix problem and gives you alphabetically sorted output, you still have neither (inline) control over inclusion of hidden items nor access to
ls
's many other sorting / output-format options.
- However, while this addresses the prefix problem and gives you alphabetically sorted output, you still have neither (inline) control over inclusion of hidden items nor access to
-
-
Hans Roggeman's
ls
+grep
answer is pragmatic, but locks you into using long (-l
) output format.
To address these limitations I wrote the fls
(filtering ls) utility,
- a utility that provides the output flexibility of
ls
while also providing type-filtering capability, - simply by placing type-filtering characters such as
f
for files,d
for directories, andl
for symlinks before a list ofls
arguments (runfls --help
orfls --man
to learn more).
Examples:
fls f # list all files in current dir.
fls d -tA ~ # list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)
Installation
Supported platforms
- When installing from the npm registry: Linux and macOS
- When installing manually: any Unix-like platform with Bash
npm registry
From theNote: Even if you don't use Node.js, its package manager, npm
, works across platforms and is easy to install; try
curl -L https://git.io/n-install | bash
With Node.js installed, install as follows:
[sudo] npm install fls -g
Note:
-
Whether you need
sudo
depends on how you installed Node.js / io.js and whether you've changed permissions later; if you get anEACCES
error, try again withsudo
. -
The
-g
ensures global installation and is needed to putfls
in your system's$PATH
.
Manual installation
- Download this
bash
script asfls
. - Make it executable with
chmod +x fls
. - Move it or symlink it to a folder in your
$PATH
, such as/usr/local/bin
(macOS) or/usr/bin
(Linux).
Solution 4 - Bash
Listing content of some directory, without subdirectories
I like using ls
options, for sample:
> - -l
use a long listing format
> - -t
sort by modification time, newest first
> - -r
reverse order while sorting
> - -F
, --classify
append indicator (one of */=>@|) to entries
> - -h
, --human-readable
with -l and -s, print sizes like 1K 234M 2G etc...
Sometime --color
and all others. (See ls --help
)
Listing everything but folders
This will show files, symlinks, devices, pipe, sockets etc.
so
find /some/path -maxdepth 1 ! -type d
could be sorted by date easily:
find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +
Listing files only:
or
find /some/path -maxdepth 1 -type f
sorted by size:
find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +
Prevent listing of hidden entries:
To not show hidden entries, where name begin by a dot, you could add ! -name '.*'
:
find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +
Then
You could replace /some/path
by .
to list for current directory or ..
for parent directory.
Solution 5 - Bash
You can also use ls
with grep
or egrep
and put it in your profile as an alias:
ls -l | egrep -v '^d'
ls -l | grep -v '^d'
Solution 6 - Bash
find files: ls -l /home | grep "^-" | tr -s ' ' | cut -d ' ' -f 9
find directories: ls -l /home | grep "^d" | tr -s ' ' | cut -d ' ' -f 9
find links: ls -l /home | grep "^l" | tr -s ' ' | cut -d ' ' -f 9
tr -s ' ' turns the output into a space-delimited file the cut command says the delimiter is a space, and return the 9th field (always the filename/directory name/linkname).
I use this all the time!
Solution 7 - Bash
You are welcome!
ls -l | grep '^-'
cut
or awk
.
Looking just for the name, pipe to ls -l | grep '^-' | awk '{print $9}'
ls -l | grep '^-' | cut -d " " -f 13
Solution 8 - Bash
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }
added xargs
to make it works, and used -1
instead of -l
to show only filenames without additional ls
info
Solution 9 - Bash
You can one of these:
echo *.* | cut -d ' ' -f 1- --output-delimiter=$'\n'
echo *.* | tr ' ' '\n'
echo *.* | sed 's/\s\+/\n/g'
ls -Ap | sort | grep -v /
Solution 10 - Bash
Just adding on to carlpett's answer. For a much useful view of the files, you could pipe the output to ls.
find . -maxdepth 1 -type f|ls -lt|less
Shows the most recently modified files in a list format, quite useful when you have downloaded a lot of files, and want to see a non-cluttered version of the recent ones.
Solution 11 - Bash
"find '-maxdepth' " does not work with my old version of bash, therefore I use:
for f in $(ls) ; do if [ -f $f ] ; then echo $f ; fi ; done