1. Overview

The basic ls command in Linux is a common command for listing files and directories. Beyond a simple listing, ls also provides several options for displaying details about files and their types. This enables users to filter a given listing based on the file type.

In this tutorial, we’ll explore how to list files by type using the ls command.

2. Sample Task

Let’s suppose we have a directory that contains a set of files. We can list its contents using the ls command:

$ ls
dir1  dir2  file1  file2  softlink1  softlink2

The names of the listed objects suggest that there are two subdirectories, dir1 and dir2, two regular files, file1 and file2, and two symbolic links, softlink1 and softlink2. However, we can’t be sure because a simple listing doesn’t show the file types of the listed objects.

Our objective is to list files based on a specific type. In other words, we’d like to filter out the listing based on file type.

Let’s explore different ways to accomplish this task.

3. Using ls -l

The -l option with ls enables the long listing format which displays details about each file:

$ ls -l
total 8
drwxr-xr-x 2 sysadmin sysadmin 4096 Jul 24 13:44 dir1
drwxr-xr-x 2 sysadmin sysadmin 4096 Jul 24 13:44 dir2
-rw-r--r-- 1 sysadmin sysadmin    0 Jul 24 13:44 file1
-rw-r--r-- 1 sysadmin sysadmin    0 Jul 24 13:44 file2
lrwxrwxrwx 1 sysadmin sysadmin    5 Jul 24 13:45 softlink1 -> file1
lrwxrwxrwx 1 sysadmin sysadmin    5 Jul 24 13:45 softlink2 -> file2

The very first character indicates the file type for a given object. In this case, we can see the d character which stands for directories, the symbol which represents regular files, and the l character representing symbolic links.

In general, there are several possible file types:

Symbol

File Type

regular file

d

directory

l

symbolic link

p

named pipe

c

character device, e.g., /dev/tty1

b

block device, e.g., /dev/sda2

s

socket

Therefore, to filter the listing by file type, we can use different commands.

3.1. Filter by Type via grep

Let’s suppose we want to list only regular files with grep:

$ ls -l | grep '^-'
-rw-r--r-- 1 sysadmin sysadmin    0 Jul 24 13:44 file1
-rw-r--r-- 1 sysadmin sysadmin    0 Jul 24 13:44 file2

We use grep to match lines that begin with a hyphen () symbol. The caret (^) character represents the start of a line.

3.2. Output Only Filenames via awk

If we want to extract only the file names, we can pass the result via a pipe to awk:

$ ls -l | grep '^-' | awk '{print $NF}'
file1
file2

Here, awk uses its built-in NF (Number of Fields) variable to print out the last field of the provided input.

Alternatively, awk is also able to match specific patterns, so we can eliminate the use of grep:

$ ls -l | awk '/^-/ {print $NF}'
file1
file2

awk can match the same pattern used earlier with grep. It then prints the last field of each line where the pattern is detected.

3.3. Output Only Filenames via rev and cut

Another approach is to use rev and cut to extract the file names:

$ ls -l | grep '^-' | rev | cut -d ' ' -f 1 | rev
file1
file2

The procedure involves three steps:

  1. first rev command reverses the order of the character in each line
  2. cut command extracts the first field as specified by the -f option; it also uses a space delimiter as set by the -d option
  3. last rev undoes the initial reversal of characters

This way, we effectively extract the last field of each line.

4. Using find

Notably, we can also get files by type using the find command:

$ find . -maxdepth 1 -type f
./file2
./file1

We use the -maxdepth option to specify a maximum depth for the search. In this case, the depth is one level only, meaning it’s within the current directory. We also specify the file type using the -type option, which in this case, is set to a regular file (f).

Similarly, we can list symbolic links by only modifying the file type:

$ find . -maxdepth 1 -type l
./softlink2
./softlink1

We set the -type option to l for symbolic links.

We can also list directories by setting the -type option to d:

$ find . -maxdepth 1 -type d
.
./dir2
./dir1

Subsequently, the result includes the current directory (.). Therefore, to remove it from the output, we can use the -name option:

$ find . -maxdepth 1 -type d ! -name '.'
./dir2
./dir1

In this case, we exclude (!) objects with the dot name (.), representing the current directory.

Thus, we can use the find command with the character code for each file -type to get only the relevant files in our result.

5. Conclusion

In this article, we explored different ways to list files by type. In particular, we saw how to use ls -l in combination with grep to filter out objects based on file type. We also explored ways to extract the file names from a listing by either using awk or combining rev and cut. Finally, we also looked at the find command as an alternative for listing files by type.