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?
-
Possible duplicate of [How to get the list of files in a directory in a shell script?](https://stackoverflow.com/q/2437452), [How to list files in directory using bash?](https://stackoverflow.com/q/7265272), [Shell script print out file names when given a folder](https://stackoverflow.com/q/45705896), [List files in current directory with full path using Bash](https://stackoverflow.com/q/22992790), [What expands to all files in current directory recursively?](https://stackoverflow.com/q/1690809), [Show files in current directory using Git Bash?](https://stackoverflow.com/q/28738331), etc. – jww May 30 '18 at 01:09
-
Possible duplicate of [How to get the list of files in a directory in a shell script?](https://stackoverflow.com/questions/2437452/how-to-get-the-list-of-files-in-a-directory-in-a-shell-script) – codeforester May 30 '18 at 01:43
-
1None of the proposed duplicates seem to implement the requirement to omit directories. – tripleee May 30 '18 at 04:12
13 Answers
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.
- 12,203
- 5
- 48
- 82
-
After my comment to mklement0's answer, I realized that "find ./*.png -maxdepth 1 -type f > pngs.txt" would probably accomplish the same. It does. Without installing a script. – Alex Hall Sep 26 '15 at 05:29
-
2`find` on mac, does not have neither `-type`, nor `-maxdepth` options. – Timofey Jul 03 '16 at 17:36
-
2@Tim: `-type` and `-maxdepth` aren't _options_ in the normal sense; BSD `find` (as used on OS X) calls them _primaries_, and they must come _after_ the filename operand(s) (`.`, in this case; note that, unlike on Linux, the BSD version needs at least one explicit filename operand); the command in this answer definitely works on a Mac. – mklement0 Jul 07 '16 at 16:42
-
1@AlexHall: That's a clever solution (though I suggest `find *.png -maxdepth 0 -type f` to avoid the `./` prefix in the output filenames; also note the `-maxdepth` of `0`, not `1`), as long as all you need is the file _names_ in _alphabetical order_. If you want what `ls` can otherwise do for you (different output format/ordering, inline control over whether hidden items are included or not), supplemented with [multi-]type filtering, the script from my answer can help. – mklement0 Jul 07 '16 at 17:09
-
2To contrast `find * -maxdepth 0 -type f` (an alternative derived from @AlexHall's comment) with `find . -maxdepth 1 -type f` from the answer: `find . ...` invariably includes hidden items, invariably prefixes output filenames with `./`, and, with GNU `find` (Linux), typically outputs an unsorted list. `find * ...`, due to letting the _shell_ perform globbing up front, by default excludes hidden items (can be changed with `shopt -s dotglob`), outputs mere filenames (no prefix), sorted alphabetically. Neither approach includes _symlinks to_ files; use option `-L` to do so. – mklement0 Jul 07 '16 at 17:22
-
@Tim yes, basically because it is not POSIX: http://pubs.opengroup.org/onlinepubs/009695399/utilities/find.html `ls -p | grep -v` is though: https://stackoverflow.com/questions/10574794/how-to-list-only-files-in-bash/46135507#46135507 – Ciro Santilli OurBigBook.com Dec 09 '18 at 18:30
ls -p | grep -v /
ls -p lets you show / after the folder name, which acts as a tag for you to remove.
- 2,292
- 1
- 17
- 22
-
1It's nice to see an example using `ls` in addition to `find`, since the latter returns relative paths and the former only filenames. Use the right tool for the job. – Ben Amos Mar 21 '18 at 19:05
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;
alsofindinvariably finds hidden items too, whereasls' behavior depends on the presence or absence of the-aor-Aoptions.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+grepanswer 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
lswhile also providing type-filtering capability, - simply by placing type-filtering characters such as
ffor files,dfor directories, andlfor symlinks before a list oflsarguments (runfls --helporfls --manto 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
From the npm registry
Note: 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
sudodepends on how you installed Node.js / io.js and whether you've changed permissions later; if you get anEACCESerror, try again withsudo.The
-gensures global installation and is needed to putflsin your system's$PATH.
Manual installation
- Download this
bashscript 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).
- 382,024
- 64
- 607
- 775
-
1Brilliant. Even if it involves creating another script. I copied and pasted from the plain text source you link to, into a text file, and ran it in Cygwin with this command: fls.sh f *.png > pngs.txt And bingo: a list of .png files without paths. But really, ls doesn't have an option comparable to DOS' "dir /b" switch? I looked through the contents of ls' --help output, and nothing of the sort is there, at least. – Alex Hall Sep 26 '15 at 05:25
-
1@AlexHall: Thanks; tl;dr: try `-1` (the number one); `ls` actually defaults to "bare" output, i.e., filenames only, but when outputting to a terminal uses a column-based layout (multiple filenames per line). To get one filename per output line (which is what `dir /b` does, if memory serves), use the `-1` option, which is actually implicitly on when stdout is _not_ connected to a terminal, such as when sending to a pipe or output file. – mklement0 Sep 26 '15 at 13:23
Listing content of some directory, without subdirectories
I like using ls options, for sample:
-luse a long listing format-tsort by modification time, newest first-rreverse order while sorting-F,--classifyappend indicator (one of */=>@|) to entries-h,--human-readablewith -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.
- 64,122
- 17
- 116
- 137
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'
- 2,446
- 15
- 35
-
I wouldn't put this in a script for the reason given above, but another quick-and-dirty solution: ls -F | grep -v '/$' – mooie Jan 25 '19 at 11:33
-
@mooie, what does the '/$' mean or why does it remove the directories from the output of ls? – Classified Apr 07 '23 at 00:24
-
1@Classified "ls -F" displays a slash ("/") immediately after each pathname that is a directory. "grep" uses the dollar sign ("$") to indicate an end of a line. So "grep '/$'" would match all lines outputted by "ls -F" that end in a slash, i.e. directories. "grep -v" prints all non-matching lines, i.e. everything but directories, which will be file names (and symbolic links). – mooie Apr 08 '23 at 10:30
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!
- 47
- 2
-
-
use "9-" to get everything from the 9th field on. Links also are affected by this since they'll be after the 9th field. – Richard Nov 16 '20 at 16:11
You are welcome!
ls -l | grep '^-'
Looking just for the name, pipe to cut or awk.
ls -l | grep '^-' | awk '{print $9}'
ls -l | grep '^-' | cut -d " " -f 13
- 6,980
- 2
- 39
- 44
{ 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
-
This has some merit, in that it enforces sorting by time, though there are arguably less clumsy ways to do that with `find -printf0 '...' | sort -z` – tripleee May 30 '18 at 04:11
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 /
- 93
- 14
This method does not use external commands.
bash$ res=$( IFS=$'\n'; AA=(`compgen -d`); IFS='|'; eval compgen -f -X '@("${AA[*]}")' )
bash$ echo "$res"
. . .
- 1,777
- 1
- 19
- 17
to list only file names (and directories at final point) without folders and anything else (properties, sizes etc) I used:
ls -aRp
- a=all entries (not ignore entries start with ".")
- R=recursive (in all subfolders)
- p=append "/" indicator to directories (if you like to clean them later) eg. /temp/list/a1/ will be listed as /a1 only
if you like to compare file existence in two different places then apply this too but it sort all files and directories independently of folder structure.
ls -aRp | sort --dictionary-order
- 874
- 9
- 24
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.
- 1
- 3
-
3This probably doesn't behave as you expect! `ls` doesn't read standard input, so it's useless to pipe anything to `ls`. Did you miss `xargs`? – gniourf_gniourf Mar 04 '15 at 07:12
-
To put it differently: the `find` command in this answer is completely _ignored_; the overall command is the same as `ls -lt | less`, which performs _no_ type filtering. – mklement0 Jul 07 '16 at 17:34
-
1Though with GNU `find` you could do `find . -maxdepth 1 -type f -ls`. It also seems to work on Mac OS, though I believe `-maxdepth` and `-ls` are not properly portable options. – tripleee May 30 '18 at 04:08
"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
-
The use of `for f in $(ls)` is doubly wrong. You could fix that with `for f in *`but then it would break because you are not quoting the argument to `echo` properly. – tripleee May 30 '18 at 04:06