112

I figure there has to be a way of making ls only display non-directories, but the man page doesn't make it obvious

3

8 Answers 8

138
ls -p | grep -v /

Using ls -p tells ls to append a slash to entries which are a directory, and using grep -v / tells grep to return only lines not containing a slash.

14
  • 1
    I checked this one because it's my favorite answer (while i did upvote all of them), but now trying to find a way to put it in columns and reverse the order of output...
    – user453720
    Aug 12, 2016 at 12:11
  • "You can use 1 switch for single column list" sorry, i did try to figure out what you meant by that, i would appreciate and example/explanation if you would, i only know what a switch is in regards to C programming
    – user453720
    Aug 19, 2016 at 0:30
  • @sdkks You don't need the 1 switch when piping the output as it will default to single column in that situation. If that is what you were meaning. Aug 21, 2016 at 23:27
  • 1
    -p will not add the / suffix for symbolic links that point to directories. Keep that in mind. Oct 16, 2022 at 22:56
  • 1
    -v is --invert-match
    – Timo
    Feb 7, 2023 at 15:40
36

You may try this:

find . -maxdepth 1 -not -type d

And map this to a special alias.

But if you're really keen on using the ls command, here:

ls -p | egrep -v /$

1
  • 4
    find . -maxdepth 1 -not -type d | xargs ls - literally make ls show only the non-directory files.
    – Wil
    Nov 3, 2020 at 23:55
12

Alternatively:

ls -lAh | grep -v '^d'

This method lists in

  • -l Long list format
  • -A Displays almost all (show hidden files but don't show . and ..)
  • -h Human readable file sizes

while grep

  • -v Don't show matching records
  • Regular expression filter ^d - Those start with letter d (for directory) i.e drwxrwxr-x <some file details> <foldername>

If you don't want to type every time, you may make it into an alias for your bash/shell profile.

4
ls -F | grep -v /

Above command displays files, But it includes symlinks, pipes, etc. If you want to eliminate them too, you can use one of the flags mentioned below.

ls -F appends symbols to filenames. These symbols show useful information about files.

ls -F | grep -Ev '/|@|*|=|>|\|'

Above command displays only files.

1
  • Executables are also files. If you want loop files incl. executables, but no links, since they could be folders as well, use for file in $(ls -1F "$path" | grep -Ev "\||/|@|=|>"); do and access the full path using $path/${file//\*}. Oct 16, 2022 at 23:15
4

If you want only files and don't want to perform any operation on them, then run:

ls -lA | grep -v '^d'

Or, if you want to iterate on each file, then for me this works:

ls *.?*
1
  • Using long listing with -l switch will be slow if you have many files.
    – EsmaeelE
    Jan 16, 2023 at 19:48
4

If you only want to see only files, directories or both.

Or if you want to see hidden files, directories or not.

Use these bash functions:

showVisibleFilesOnly() {
  ls -p | grep -v /
}
showVisibleFoldersOnly() {
  ls -p | grep / | grep "^."
}

showOnlyFilesIncludingHidden() {
  ls -Ap | grep -v / | grep "^."
}
showOnlyFoldersIncludingHidden() {
  ls -Ap | grep / | grep "^."
}

showHiddenFoldersOnly() {
  ls -Ap | grep / | grep "^\." | grep "\."
}
showHiddenFilesOnly() {
  ls -Ap | grep -v / | grep "^\." | grep "\."
}

showAllFilesAndFoldersIncludingHidden() {
  ls -Ap
}

showHiddenFilesAndFoldersOnly() {
  ls -Ap | grep "^\."
}

1
  • Now you can have exactly what you want when you want it with ease Mar 8, 2021 at 23:02
1

I saw in your( @thinksinbinary ) comment on the answer by @thomasrutter , that you wanted to be able to print them in reverse order and in columns. You probably have already figured it out or moved on, but here it is:

ls -pr | grep -v / | column
  • -p adds the forward slash ('/') to the directory names
  • -r reverses the order of output
  • -v lets grep do an inverse search to print everything except the directories (everything that doesn't have the '/' that -p put there)
  • "column puts it in columns" - Captain Obvious
1
  • 1
    i do think it's cool that on the ubuntu forum people still comment on and read your posts after a long time. I've been wanting to get back into linux in order to learn assembly and operating systems since doing so on windows is much more difficult. Thanks!
    – user453720
    Oct 30, 2019 at 22:22
1

You might want to use du instead of ls. It will only output files. Then just awk '{print $2}' to output only the file path.

You have to use the -d option with du to limit depth. http://linuxcommand.org/lc3_man_pages/du1.html

3
  • However, this would show the files even in subdirectories of subdirectories.
    – Kulfy
    Oct 31, 2020 at 10:18
  • That is true. You can add the -d flag to limit the depth though. I have added an edit to my response to reflect that.
    – mixcocam
    Nov 2, 2020 at 15:15
  • 1
    Yeah. But that would still show directories, for example, Desktop when run from $HOME and won't be an answer to this question since the questioner wants to list files only.
    – Kulfy
    Nov 3, 2020 at 13:20

You must log in to answer this question.