28

I want to create a list of all the files in a directory, without listing any of the subdirectories that reside in that same directory, and print that list to a new file.

ls -d * > filelist

will create a list of all the files in the current directory, but it also lists the subdirectories in the current directory. I tried the find command using the -maxdepth 1 option - however, the output format is a problem as find also prints out the path along with the file names.

If anyone can please tell me perhaps another command or options to use that will produce an output list of just the files in a directory and not the names of the subdirectories or their contents, I would appreciate it.

3

8 Answers 8

23

Find-based solution:

find . -maxdepth 1 -type f -printf '%f\n'

Bash-based solution:

for f in *; do [[ -d "$f" ]] || echo "$f"; done
##  or, if you want coloured output:
for f in *; do [[ -d "$f" ]] || ls -- "$f"; done

The bash-based solution will get you everything that isn't a directory; it will include things like named pipes (you probably want this). If you specifically want just files, either use the find command or one of these:

for f in *; do [[ -f "$f" ]] && echo "$f"; done
##  or, if you want coloured output:
for f in *; do [[ -f "$f" ]] && ls -- "$f"; done

If you're going to be using this regularly, you can of course put this into an alias somewhere in your ~/.bashrc:

alias lsfiles='for f in *; do [[ -f "$f" ]] && ls -- "$f"; done'

Since you noted in the comments that you're actually on OSX rather than Ubuntu, I would suggest that next time you direct questions to the Apple or more general Unix & Linux Stack Exchange sites.

1
  • 1
    Make sure to check that these solutions are correct for you based on whether or not you want to include hidden files. Sep 15, 2015 at 21:47
10

List filenames only:

 1. ls -p | grep -v /                                   (without hidden files)
 2. ls -l | grep ^- | tr -s ' ' | cut -d ' ' -f 9       (without hidden files)
  
 a) ls -pa | grep -v /                                  (with hidden files)
 b) ls -la | grep ^- | tr -s ' ' | cut -d ' ' -f        (with hidden files)

List directories only:

 1. ls -p | grep /                                      (without hidden)
 2. ls -l | grep ^d | tr -s ' ' | cut -d ' ' -f 9       (without hidden) 

  a) ls -pa | grep /                                     (with hidden)
 b) ls -l | grep ^d | tr -s ' ' | cut -d ' ' -f 9       (with hidden)

grep -v -e ^$ is to remove blank lines from the result.

More details:
ls -p flag is to put '/' at the end of the directory name, -R flag is for recursive search, -l for listing with info, -a for listing all(including hidden files) with info, grep -v flag is for result invertion and -e flag for regex matching.

9

To list regular files only:

ls -al | grep ^-

With symbolic links included:

ls -al | grep ^[-l]

Where the first character of the list describes the type of file, so - means that it's a regular file, for symbolic link is l.

Debian/Ubuntu

Print the names of the all matching files (including links):

run-parts --list --regex . .

With absolute paths:

run-parts --list --regex . $PWD

Print the names of all files in /etc that start with p and end with d:

run-parts --list --regex '^p.*d$' /etc
5

Yet another solution, a naively short one that worked for me:

ls -la | grep -E '^[^d]' > files
1
  • perfect for me, ls -alR |grep -E '^-'
    – here
    Jan 7, 2014 at 9:21
4

I would suggest to use find and just remove the directory name from the output if necessary:

find . -type f -maxdepth 1 | sed s,^./,,
1
  • 2
    -maxdepth 1 should come before any filters, and you can achieve this result without using sed with the -printf option, i.e.: find . -maxdepth 1 -type f -printf '%f\n' (this will be more efficient than using an extra program).
    – evilsoup
    Oct 2, 2013 at 7:11
3
ls -1 --file-type | grep -v '/' | sed s/@$// > filelist

Another possible option is

ls -F | grep -v '/' | sed /[@*]$// > filelist

The --file-type puts a / at the end of the folders (but also a @ at the end of symbolic links. The grep -v '/' removes the subdirectories (because they now end with a '/'). The sed s/@$// removes that @. The -1 prints one file per line so that the grep -v will work correctly.

4
  • thank you for your response. unfortunately, it's not working for me, perhaps i am executing it incorrectly. if i use the exact command you gave me, i get the following error: ls: illegal option -- - usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1] [file ...] i tried using the * wildcard character in place of as well as in conjunction with --file-type. if you could clarify i would appreciate it!
    – janet
    May 2, 2013 at 2:16
  • The command works for me (running 13.04), what version of ubuntu are you using?; -1 does not matter to grep you don't need it; if you want to includes hidden files use the -a option on ls May 2, 2013 at 2:48
  • actually, i am working on a mac. perhaps the command is slightly different on mac os x or unix?
    – janet
    May 2, 2013 at 2:50
  • 1
    You could also try ls -F | grep -v '/' | sed s/[@*]$// > filelist
    – Dr.Tower
    May 2, 2013 at 3:07
0

This will do what you want:

ls *.* > filelist
4
  • Try it in a terminal window. It does precisely what the OP was asking help for.
    – ramack
    Oct 20, 2021 at 3:02
  • 1
    In the question comment: "yes, but i don't want the folders in that directory to be listed, only want the files in that directory to be listed"
    – MadMike
    Oct 21, 2021 at 11:42
  • Your answer would work if directories don't contain a . character in their name. However, since . characters are allowed in directories' names on Linux, your command could list them as well if they exist in OP's directory. Please see this relevant thread: Is it bad practice for folder name to contain a dot (.)? How about a file name with multiple dots? Oct 23, 2021 at 12:09
  • Beast,Excellent point, I had forgotten about hidden files & directories.
    – ramack
    Oct 24, 2021 at 13:34
0

The find solution is clever, but I wanted something closer to normal ls. And something that would work for directories other than the current one. Here's bash script that does that;

#!/bin/bash
dir=${1:-.}
find $dir -maxdepth 1 -type f |sed "s#$dir/##"|sort

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .