Take the 2-minute tour ×
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.

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

./dir1
dir2 file1.txt file2.txt

./dir1/dir2
file3.txt file4.txt

but I would like a command that gives me

./dir1/file1.txt
./dir1/file2.txt
./dir1/dir2/file3.txt
./dir1/dir2/file4.txt

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

share|improve this question

2 Answers 2

up vote 8 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
2  
@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
2  
@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, 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 (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 {} +
share|improve this answer

Your Answer

 
discard

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.