How can I get ls
to spit out a flat list of recursive one-per-line paths?
For example, I just want a flat listing of files with their full paths:
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt
ls -a1
almost does what I need, but I do not want path fragments, I want full paths.
Use find:
find .
find /home/dreftymac
If you want files only (omit directories, devices, etc):
find . -type f
find /home/dreftymac -type f
If you really want to use ls
, then format its output using awk:
ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'
awk
expressions?
function lsr () { ls -R "$@" | awk ' /:$/&&f{s=$0;f=0} /:$/&&!f{sub(/:$/,"");s=$0;f=1;next} NF&&f{ print s"/"$0 }' }
so you can use lsr /path
to use this wherever
awk
code? It looks like you are using a regex to catch lines that end in ":" (the "headers" with parent directory paths), but I get lost after that and definitely don't understand the part where the last field NF
is being evaluated as true/false. Thanks!
ls -ld $(find .)
if you want to sort your output by modification time:
ls -ltd $(find .)
--sort=extension
parameter of ls
find . -name "*" -exec ls -ld '{}' \;
(that one works whatever the number of files is), but your command is way shorter to write ;)
find . -ls
.
Best command is: tree -fi
-f print the full path prefix for each file -i don't print indentations
e.g.
$ tree -fi
.
./README.md
./node_modules
./package.json
./src
./src/datasources
./src/datasources/bookmarks.js
./src/example.json
./src/index.js
./src/resolvers.js
./src/schema.js
In order to use the files but not the links, you have to remove >
from your output:
tree -fi |grep -v \>
If you want to know the nature of each file, (to read only ASCII files for example) try a while
loop:
tree -fi |
grep -v \> |
while read -r first ; do
file "${first}"
done |
grep ASCII
brew install tree
, given you are using homebrew
file
example and pipe to grep -v directory
Try the following simpler way:
find "$PWD"
find "`pwd`"
if the path contains spaces or some other special characters.
find .
? -.-
pwd
to start with, it will print absolute paths. By the way, "How is this any different than find
" ;-)
find
without an argument is a syntax error on some platforms. Where it isn't, just find
is equivalent to find .
.
Oh, really a long list of answers. It helped a lot and finally, I created my own which I was looking for :
To List All the Files in a directory and its sub-directories:
find "$PWD" -type f
To List All the Directories in a directory and its sub-directories:
find "$PWD" -type d
To List All the Directories and Files in a directory and its sub-directories:
find "$PWD"
find "$PWD" -type f | grep '\.json$'
find "$PWD/README.md"
I don't know about the full path, but you can use -R
for recursion. Alternatively, if you're not bent on ls
, you can just do find *
.
du -a
Handy for some limited appliance shells where find/locate aren't available.
awk
?
Using no external commands other than ls:
ls -R1 /path |
while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done
ls -1
is fairly standard; but try just leaving it out if it's unsupported. The purpose of that option is to force ls
to print one line per file but that's usually its behavior out of the box anyway. (But then of course, don't use ls
in scripts.) (Looking at the POSIX doco, this option was traditionally BSD only, but was introduced in POSIX in 2017.)
find / will do the trick
Run a bash command with the following format:
find /path -type f -exec ls -l \{\} \;
Likewise, to trim away -l
details and return only the absolute paths:
find /path -type f -exec ls \{\} \;
find -ls
avoids running an external process for each file and is a lot easier to type.
-exec ls \{\} \;
part, since the default behavior of find
is to print the full path. That is, find /path -type f
does the job if you don´t need the file attributes from ls -l
.
The easiest way for all you future people is simply:
du
This however, also shows the size of whats contained in each folder You can use awk to output only the folder name:
du | awk '{print $2}'
Edit- Sorry sorry, my bad. I thought it was only folders that were needed. Ill leave this here in case anyone in the future needs it anyways...
Don't make it complicated. I just used this and got a beautiful output:
ls -lR /path/I/need
ls -lR
wouldn't meet that goal.
With having the freedom of using all possible ls options:
find -type f | xargs ls -1
I think for a flat list the best way is:
find -D tree /fullpath/to-dir/
(or in order to save it in a txt file)
find -D tree /fullpath/to-dir/ > file.txt
find: illegal option -- D
Here is a partial answer that shows the directory names.
ls -mR * | sed -n 's/://p'
Explanation:
ls -mR *
lists the full directory names ending in a ':', then lists the files in that directory separately
sed -n 's/://p'
finds lines that end in a colon, strip off the colon and print the line
By iterating over the list of directories, we should be able to find the directories as well. Still workin on it. It is a challenge to get the wildcards through xargs.
Adding a wildcard to the end of an ls directory forces full paths. Right now you have this:
$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt
You could do this instead:
$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt
Unfortunately this does not print the full path for directories recursed into, so it may not be the full solution you're looking for.
ls
has a lot of pesky corner cases; see parsing ls
A lot of answers I see. This is mine, and I think quite useful if you are working on Mac.
I'm sure you know there are some "bundle" files (.app, .rtfd, .workflow, and so on). And looking at Finder's window they seem single files. But they are not. And $ ls
or $ find
see them as directories... So, unless you need list their contents as well, this works for me:
find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"
Of course this is for the working dir, and you could add other bundles' extensions (but always with a /
after them). Or any other extensions if not bundle's without the /
.
Rather interesting the ".lpdf/
" (multilingual pdf). It has normal ".pdf
" extension (!!) or none in Finder. This way you get (or it just counts 1 file) for this pdf
and not a bunch of stuff…
ls -lR
is what you were looking for, or atleast I was. cheers
ls -lR
wouldn't meet that goal.
If the directory is passed as a relative path and you will need to convert it to an absolute path before calling find. In the following example, the directory is passed as the first parameter to the script:
#!/bin/bash
# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find "$directory"
readlink
you can do directory=$(readlink -e $1)
readlink
on OS X 10.5.8 does not support -e option.
tar cf - $PWD|tar tvf -
This is slow but works recursively and prints both directories and files. You can pipe it with awk/grep if you just want the file names without all the other info/directories:
tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"
Recursive list of all files from current location:
ls -l $(find . -type f)
find . -type f -ls
which won't choke if the output from find
is too long for ls
The realpath
command prints the resolved path:
realpath *
To include dot files, pipe the output of ls -a
to realpath:
ls -a | xargs realpath
To list subdirectories recursively:
ls -aR | xargs realpath
In case you have spaces in file names, man xargs
recommends using the -o
option to prevent file names from being processed incorrectly, this works best with the output of find -print0
and it starts to look a lot more complex than other answers:
find -print0 |xargs -0 realpath
See also Unix and Linux stackexchange question on how to list all files in a directory with absolute path.
I knew the file name but wanted the directory as well.
find $PWD | fgrep filename
worked perfectly in Mac OS 10.12.1
find . -name filename
@ghostdog74: Little tweak with your solution. Following code can be used to search file with its full absolute path.
sudo ls -R / | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }' | grep [file_to_search]
If you have to search on big memory like 100 Gb or more. I suggest to do the command tree
that @kerkael posted and not the find
or ls
.
Then do the command tree
with only difference that, I suggest, write the output in the file.
Example:
tree -fi > result.txt
After, do a grep command
in file using a pattern like grep -i "*.docx" result.txt
so you not lose a time and this way is faster for search file on big memory.
https://i.stack.imgur.com/dSJzg.png
Success story sharing
ls
parameters like--sort=extension
"redeemed" by this solution?find
with the-printf
predicate allows you to do everytingls
does, and then some. However, it is not standard. You can usefind -exec stat {} \;
but unfortunately the options tostat
are not standardized, either.