Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

When I do 'ls -R' in a directory, I get something like

dir2 file1.txt file2.txt

file3.txt file4.txt

but I would like a command that gives me


such that I can use it in a for-loop to process all files.

share|improve this question
up vote 9 down vote accepted

You want find(1). This will do exactly what you want. You can also specify various filter conditions such as file type (don't include directories), newer than the time stamp on a given file etc. The man page will describe these in more detail.

Also, take a look at the -exec option; you may be able to use this instead of iterating over the output.

share|improve this answer
thanks, I never called it without arguments before :-) – thias Sep 30 '11 at 11:27
@thias Also have a look at find -ls option. – rozcietrzewiacz Sep 30 '11 at 12:10
thanks, that appears to be useful! – thias Sep 30 '11 at 12:15
@thias I'll amend Concerned's suggestion to a strong recommendation: use find … -exec. Do not use for x in $(find …): it does not work, because it can't cope with file names containing whitespace. find -exec is exactly the right tool for the job. – Gilles Sep 30 '11 at 23:16

If you're using bash ≥4 or zsh or ksh93 ≥o+1, you can make the shell do recursive globbing: the **/ wildcard matches directories at any depth. In bash, you need to enable the feature with shopt -s globstar (bash), and beware that up to bash 4.2, **/ traverses symbolic links to directories. In ksh93, you need set -o globstar (ksh93); in zsh, it's always enabled.

for x in **/*.txt; do …

If you need your script to be portable to other shells, use the find command, it's exactly the right tool for the job. Note that find is an external command that can work in two ways: it can generate a list of files, and it can execute commands for each file. If you want to execute a command for each file, use -exec:

find . -type f -name '*.txt' -exec chmod a+r {} +

1Among non-Bourne shells, fish and tcsh also have the feature

share|improve this answer

tree is also a nice tool for this.

I use

tree -Dpushfag --du

you can also add a limit in depth, for example maximum 2 levels:

tree -Dpushfag --du -L 2
share|improve this answer
very nice tool but it does not really solve the problem posed in the question (at least not with the arguments you provide) – thias Feb 6 '15 at 7:59

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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