26

I need a file (preferably a .list file) which contains the absolute path of every file in a directory.

Example dir1: file1.txt file2.txt file3.txt

listOfFiles.list:

/Users/haddad/dir1/file1.txt
/Users/haddad/dir1/file2.txt
/Users/haddad/dir1/file3.txt

How can I accomplish this in linux/mac?

25
ls -d "$PWD"/* > listOfFiles.list
  • would this work in red hat linux? – arabian_albert Mar 8 '16 at 19:07
  • 4
    That command works in any Linux or UNIX operating system. If you want to get one file per line, you need to use ls -d -1 $PWD/* – MelBurslan Mar 8 '16 at 19:11
  • 1
    if your file names are long or terminal width is narrow,, yes, that will be the case, but say you maximized the terminal window to occupy the whole screen or your file names (including the path) are really short, that will not hold true. -1 option guarantees you get one filename per line – MelBurslan Mar 8 '16 at 19:18
  • 7
    @MelBurslan 's addition is only needed if output is to a termiinal. ls detects if output is is to a file or terminal. – Runium Mar 8 '16 at 19:58
  • 7
    this will fail if there are many thousands of files in the directory, i.e. enough to exceed the maximum command line size (made more likely by the fact that the shell is expanding the filenames with full path). @Andy Dalton's find answer is a better solution, as it won't fail no matter how many files are to be listed. – cas Mar 8 '16 at 22:39
32

You can use find. Assuming that you want only regular files, you can do:

find /path/to/dir -type f > listOfFiles.list

You can adjust the type parameter as appropriate if you want other types of files.

  • 7
    +1 for pointing a more future-proof solution that ls. This find does recurse the subdirectories, for non-recursive you need to add -maxdepth 1 before -type argument. – kubanczyk Mar 8 '16 at 21:19
  • @AndyDalton How to get the same to an array in bash – Kasun Siyambalapitiya Jan 8 '18 at 8:56
11

Note that in:

ls -d "$PWD"/* > listOfFiles.list

It's the shell that computes the list of (non-hidden) files in the directory and passes the list to ls. ls just prints that list here, so you could as well do:

printf '%s\n' "$PWD"/*
  • 3
    Using printf has the added bonus that you won't get a 'command line too long' error if you have thousands of files as printf is not run as a separate process. – Adrian Pronk Mar 10 '16 at 9:07
  • 1
    @AdrianPronk, yes, except in shells where printf is not built-in like pdksh and some of its derivatives or most versions of the Bourne shell. One drawback compared to ls -d is that if there's no non-hidden file in there, it will print /path/to/* while ls will give you an error about that file not existing instead. – Stéphane Chazelas Mar 10 '16 at 9:44
10

To see just regular files --

find "$PWD" -type f  > output
3

You can just use realpath or readlink:

ls | xargs realpath
  • xargs build and execute command lines from standard input.
  • realpath: return the canonicalized absolute pathname
  • readlink: read value of a symbolic link
  • realpath: command not found – rogerdpack Mar 23 '18 at 21:28
  • @rogerdpack do you have coreutils package installed? I get that info with dpkg -S /usr/bin/realpath. Check out this. – Pablo Bianchi Mar 24 '18 at 2:52
3

Another way with tree, not mentioned here, it goes recursively and unlike find or ls you don't have any errors (like: Permission denied, Not a directory) you also get the absolute path in case you want to feed the files to xargs or other command

tree -fai /pathYouWantToList >listOfFiles.list

the options meaning:

-a     All  files  are  printed.  By default tree does not print hidden files (those beginning with a dot
       `.').  In no event does tree print the file system constructs `.'  (current  directory)  and  `..'
       (previous directory).

-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

-f     Prints the full path prefix for each file.

To install tree:

sudo apt install tree on Ubuntu/Debian

sudo yum install tree on CentOS/Fedora

sudo zypper install tree on OpenSUSE

  • 1
    tree: command not found – rogerdpack Mar 23 '18 at 21:28
  • @rogerdpack sudo apt install tree on Ubuntu sudo yum install tree on CentOS sudo zypper install tree on OpenSUSE – Eduard Florinescu Mar 24 '18 at 0:27
  • 1
    brew install tree on Mac – oOEric Feb 11 at 7:42
2

In a past Linux environment, I had a resolve command that would standardize paths, including making a relative path into an absolute path. I can't find it now, so maybe it was written by someone in that organization.

You can make your own script using functions in the Python or Perl standard libraries (and probably other languages too).

resolve.py :

#!/bin/env python

import sys
import os.path

for path in sys.argv:
    print os.path.abspath(path)

resolve.pl :

#!/bin/env perl

use warnings;
use Cwd qw ( abs_path );

foreach (@ARGV) {
    print abs_path($_), "\n";
}

Then, you would solve your problem with:

resolve.py * > listOfFiles.list

With this command, you can also do things like this:

cd /root/dir1/dir2/dir3
resolve.py ../../dir4/foo.txt
# prints /root/dir1/dir4/foo.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.