Marcio Cunha

How to List Only Folders Excluding Common Files in the Terminal Using LS Arguments

Learn how to filter the output of the ls command in Linux and macOS to display only directories, eliminating common files using native arguments, regular expressions, and smart pipes.

Marcio Cunha12 min
Also available in:EspañolPortuguês
Summary
  • The standard ls command displays mixed files and folders, requiring filters to isolate directory structures.
  • Combining the -d parameter with a trailing slash restricts the listing exclusively to folders.
  • Using pipes with grep allows refining the search to hide files even without complex parameters.
  • Modern tools like find provide robust alternatives when the directory tree is deep.
  • Creating aliases in the terminal configuration file simplifies this recurring daily operation.

The Challenge of Filtering Directories in the Terminal

When opening the terminal in Unix-based systems like Linux and macOS, the ls command is our primary touchpoint for understanding what resides inside a folder. However, the default behavior of this command is to list both files and directories at once, creating considerable visual clutter. In projects with hundreds of configuration files, scripts, and assets scattered around, finding only subfolders requires mental effort and extra commands. In practice, this means we lose precious time trying to discern the actual project architecture amidst so much textual noise.

For those starting in software engineering or systems administration, this visual confusion is one of the initial barriers to using the command line. Graphical interfaces have accustomed us to navigating folders in isolation, whereas the terminal dumps everything onto the same screen. Understanding how to manipulate native ls arguments is the first step toward regaining control and speeding up your daily workflow. Let's explore the fundamental techniques that transform this noisy listing into a clean, structured overview of directories.

Understanding the Native Behavior of the LS Command

The ls command features dozens of flags, which are letters preceded by a hyphen that modify its behavior. By default, when you type ls and press Enter, the operating system reads the metadata of the current directory and prints all visible items in alphabetical order. If the current folder contains files like index.js, README.md, and a folder named src, they will all appear side by side or stacked. The problem is that ls treats directories merely as a specific type of file, without immediate visual separation.

To mitigate this, many developers resort to visual shortcuts, but the true power lies in knowing the internal arguments of the command itself. The -l argument, for instance, displays the long listing mode, detailing permissions, owner, size, and modification date. In the first column of this long listing, a letter indicates the item type: a hyphen (-) signifies a common file, while the letter 'd' indicates a directory (folder). However, using just -l still shows the files while adding details about them, which does not solve our exclusion problem.

The Direct Solution Using the Directory Parameter

The most elegant and native way to list only folders using ls itself involves the -d (directory) argument. In practice, -d tells the command to list the directories themselves rather than the contents inside them. When we run just ls -d, the terminal returns only the current dot (.) because it interprets that you want information about the current directory. To make the magic happen and list all subfolders, we need to combine this argument with a matching pattern known as globbing.

The pattern most used by system administrators consists of adding a trailing slash (/) at the end of the search argument. By running the command ls -d */, we tell the terminal to look only for items ending with a slash, which in the Unix file architecture is the exclusive signature of directories. The result is a clean listing containing strictly the folders in the current directory. This method is extremely fast because it requires no external processing or additional tools, running directly within the command interpreter.

Hiding Hidden Files and Adjusting the Display

In the Unix universe, files and folders starting with a dot (like .git or .env) are considered hidden and do not appear in a standard listing. When we use the trick ls -d */, hidden folders that are also directories are left out of the fun. To include these hidden folders in our directory-restricted listing, we need to invoke the -a (all) argument, which reveals everything hidden under the file system's rug.

The perfect combination to cover absolutely every folder, including hidden ones, becomes ls -d .*/ */. Here we combine two patterns: the first .*/ captures hidden directories (as well as the special . and .. directories representing current and parent), while the second */ captures common folders. Although it works perfectly, this output may be accompanied by a trailing slash at the end of each folder name, which is great for visual identification but may require minor adjustments if you plan to use this output in automation scripts.

Filtering Results with Pipes and Regular Expressions

Sometimes, native ls arguments need external help for more specific use cases, and that is where pipes (represented by the | character) come into play. A pipe acts like a hose directing the output of one command into the input of another. If we want to list all items in long format and then filter only lines starting with the letter 'd', we can combine ls with the grep utility, which is a text pattern matcher.

The complete command looks similar to ls -l | grep '^d'. In practice, ls -l generates the detailed list with permissions, and grep searches through this text looking strictly for lines whose first character is 'd' (indicated by the caret at the beginning). Although this approach displays full folder metadata and filters common files, it brings the inconvenience of including the total block count directory that ls usually displays at the top. It is an excellent exercise in command composition, showing how the terminal allows creating modular solutions.

Comparing Native Approaches and Modern Alternatives

Although the ls command is ubiquitous, software engineering has evolved and introduced alternative tools to manage the file system with greater precision. The find command, for instance, was specifically designed to sweep directory trees based on complex search criteria such as size, modification date, and file type. When comparing ls with find for the task of listing folders, we notice clear differences in purpose and operational trade-offs that directly affect performance in large repositories.

ApproachAdvantagesLimitations
ls -d */Native, fast, and requires no external tools.Limited to the current directory, requires complex patterns for recursion.
ls -l | grep '^d'Shows full folder permissions and metadata.More verbose and less efficient for simple automations.
find . -maxdepth 1 -type dHighly robust, predictable, and safe for scripts.Less intuitive syntax for terminal beginners.

Automating the Flow with Terminal Aliases

If you found yourself typing ls -d */ repeatedly throughout the day, the best engineering practice is to automate this repetition. Modern terminals like Bash and Zsh allow creating aliases that turn long commands into short, easy-to-remember words. You can add a custom shortcut in your shell configuration file (such as .bashrc or .zshrc) so a single word executes directory filtering instantly.

To implement this, simply open your text configuration file and add a line like alias lsd='ls -d */'. After saving and reloading the terminal, whenever you type lsd, the system executes the directory-restricted listing without you needing to remember the slash or the -d argument. This small optimization reduces daily cognitive friction, allowing you to navigate the file system with the fluidity of a graphical interface yet with the unmatched speed of the terminal.

Final Thoughts on Directory Manipulation

Mastering the details of basic terminal commands is what separates an ordinary user from an efficient technology professional. The command ls, despite appearing simple at first glance, hides an impressive level of flexibility when combined with targeted arguments and character patterns. Understanding the trade-off between using native flags, text filters, or alternative commands ensures you always choose the right tool for every level of operational complexity.

Constant practice of these concepts in the daily development environment turns complex commands into automatic muscle memory. By eliminating the visual noise of unnecessary files on the terminal's black screen, we free up mental focus for what truly matters: solving architectural problems, writing clean code, and keeping our systems organized and productive.