49

I am looking for a way to list all the files in a directory excluding directories themselves, and the files in those sub-directories.

So if I have:

./test.log
./test2.log
./directory
./directory/file2

I want a command that returns: ./test.log ./test2.log and nothing else.

Alex
  • 6,843
  • 10
  • 52
  • 71

8 Answers8

83

If you want test.log, test2.log, and file2 then:

find . -type f

If you do not want file2 then:

find . -maxdepth 1 -type f
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
22

If you need symlinks, pipes, device files and other specific elements of file system to be listed too, you should use:

find -maxdepth 1 -not -type d

This will list everything except directories.

anton_rh
  • 8,226
  • 7
  • 45
  • 73
  • This is exactly what I was looking for. I wanted to list all types _except_ directories. I was doing something like `find / -group xxx | xargs ls -l`. This would `ls -l ` and then `ls -l ` each file in the dir. But using `-not -type d` excluded dirs from the output. Note that `! -type d` also works (and claims to be POSIX compliant per the man page) – sherrellbc Jun 23 '21 at 18:06
3

using find is simple as:

find . -maxdepth 1 -type f
dfa
  • 114,442
  • 31
  • 189
  • 228
1

find only regular files

Use the -type f option with find to find only regular files. OR, to be even more-inclusive, use -not -type d to find all file types except directories.

When listing all files, I like to also sort them by piping to sort -V, like this:

# find only regular files
find . -type f | sort -V

# even more-inclusive: find all file types _except_ directories
find . -not -type d | sort -V

From man find:

-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)

To search for more than one type at once, you can supply the combined list of type letters separated by a comma , (GNU extension).

How to store the output of find (a multi-line string list of files) into a bash array

To take this one step further, here is how to store all filenames into a bash indexed array called filenames_array, so that you can easily pass them to another command:

# obtain a multi-line string of all filenames
filenames="$(find . -type f | sort -V)"
# read the multi-line string into a bash array
IFS=$'\n' read -r -d '' -a filenames_array <<< "$filenames"

# Now, the the variable `filenames_array` is a bash array which contains the list 
# of all files! Each filename is a separate element in the array.

Now you can pass the entire array of filenames to another command, such as echo for example, by using "${filenames_array[@]}" to obtain all elements in the array at once, like this:

echo "${filenames_array[@]}"

OR, you can iterate over each element in the array like this:

echo "Files:"
for filename in "${filenames_array[@]}"; do
    echo "  $filename"
done

Sample output:

Files:
  ./file1.txt
  ./file2.txt
  ./file3.txt

References:

  1. I was reminded of find . -type f from the main answer by @John Kugelman here.
  2. I borrowed the part to read the multi-line string into a bash array from my own answer here: How to read a multi-line string into a regular bash "indexed" array
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
0
find . -type f
amrox
  • 6,207
  • 3
  • 36
  • 57
0
find /some/directory -type f
Eric M
  • 1,027
  • 2
  • 8
  • 21
0
$ find . -type f -print

Each file will be on its own line. You must be in the directory you want to search.

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
Rob Jones
  • 4,925
  • 3
  • 32
  • 39
-1

One more option

ls -ltr | grep ^-

to list all files, while

ls -ltr | grep ^d

to list all directories

luw
  • 207
  • 3
  • 14
Sachin
  • 20,805
  • 32
  • 86
  • 99