Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

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

I have a lot of directories and sub-directories. I want to recursively remove one specific file from a directory if it's the only one there. Also assume that there are no sub-directories in that directory. So, to summarize, the assumptions are:

  • The file name is README.TXT (case insensitive)
  • There are no other files or directories in the directory where that file is found


 mkdir usecase
 cd usecase
 mkdir destroy_this
 touch destroy_this/readme.txt
 mkdir do_not_destroy_this
 touch do_not_destroy_this/readme.txt
 touch do_not_destroy_this/something-else.txt
 mkdir do_nothing
 cd do_nothing
 mkdir rm_this
 touch rm_this/README.TXT
 cd ..
 mkdir do_nothing_here
 cd do_nothing_here
 mkdir has_sub_dir
 cd ..

Running the above would results in this tree structure:

$ tree .
`-- usecase
    |-- destroy_this
    |   `-- readme.txt
    |-- do_not_destroy_this
    |   |-- readme.txt
    |   `-- something-else.txt
    |-- do_nothing
    |   `-- rm_this
    |       `-- README.TXT
    `-- do_nothing_here
        |-- has_sub_dir
        `-- README.TXT

This is what I've got so far:

find . -type f -iname "readme.txt" -exec sh -c 'ls $(dirname "{}") | wc -l' \;

The idea is that I count the number of files and directories and if it's one then remove the file.

share|improve this question
up vote 3 down vote accepted

What you have is a good base to start. If you modified the contents of your -exec you could introduce a if/then construct which would allow you to act on the state of the count being a 1 or not.

$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "yes"; \
        else echo "no"; \
    fi' \;

With this we could expand on the echo "yes" command to perform the actual removal of the file. Something like rm "{}" should do the trick.


$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "removing {}.."; rm "{}"; \
        else echo "no"; \
    fi' \;
removing ./usecase/destroy_this/readme.txt..
removing ./usecase/do_nothing/rm_this/README.TXT..

Running the above a 2nd time confirms the files are no longer there:

$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "removing {}.."; rm "{}"; \
        else echo "no"; \
    fi' \;
share|improve this answer
But what if the readme is in a /dir/w/\newline/readme.txt? ls will just error - it wont even read the directory entry. – mikeserv May 31 '14 at 11:47
find . -type f -iname "readme.txt" -exec sh -c '
    for f do ls -1qap ${f%/*} | 
        grep -v "\(readme.txt\$\|/\$\|.\{1,2\}\$\)" &&
    echo rm "$f" ; done' \{\} +
share|improve this answer

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.