I need to write a script that will find files that contain a string in their name. If a file exists that is the same name but without that string, I want to remove the original file.

For example, if I am in a directory with the following files:


If the substring is gom then I would consider algomb, gomba, and algomba. Removing gom from each of those names I would check for the existance of alb, ba, and alba. Of those, alb and alba do exist, so I would remove algomb and algomba leaving just


in the directory when I'm done.

Here is what I tried:


talal=`find . -type f -name "*$sz*" -exec basename {} \;`
ossz=`find . -type f -exec basename {} \;`
c=`echo ${talal%%:*}${talal##*:}`

for c in ossz; do       
    if [ ! -d ]; then
        echo "This is a directory"  
        if [ -f ];
            find .-type f -name "*$sz*" -exec basename {} \;  
            echo ${talal%%:*}${talal##*:} 

So this is works. This echo ${talal%%:*}${talal##*:} is give back the filename without "gom". But I can't compare these values with find . -type f -exec basename {} \; results.

Given that I can find the substrings, how can I test for the files and remove the appropriate ones?

  • What is the output when you execute the script? – tachomi Sep 23 '15 at 16:21

The following should do what you're asking:


find $dir -type f -name "*${sz}*" -print0 | while read -d '' -r c; do
    if [[ -f "$(echo $c | sed 's/'"${sz}"'//g')" ]]; then
        # Strip the 'echo' to have this actually do things
        echo rm -v "$c"

Some notes on the changes and fixes:

  • Find's -printf "%f\n" is preferable to -exec basename {} \;. In this case I've removed find stripping the dirname so that the script is safe for non-flat directory structures.
  • for c in ossz shouldn't have ever worked - the barename ossz isn't a variable. $ossz would've been needed.
  • Using sed is probably preferable to relying upon bash pattern matching and substitution for readability reasons.


For a directory containing the following files:

alb  alba  algomb  algomba  gomb

The script from above will output the following:

rm -v ./algomb
rm -v ./algomba
| improve this answer | |
  • So if I understand right then this script "cut" the $sz variable from all file name and the remaining will be compare with all files and if exist, then delete the file with $sz variable? For example: there are 3 files: algomba, alba, aladar, I need a script what do the following: 1. Find all files with "gom". 2. "Cut" gom from filename, and compare other files: in my example there are 1 file: algomba -> alba 3. If there is a file with this name, then delete the file, what contained "gom" : there is algomba -> cit "gom" -> alba -> alba is exist, then remove algomba. Sorry for my english – Cafu90 Sep 23 '15 at 19:01
  • Yes, that is correct. I've added a demonstration of this to my answer. Note that you'll need to set the dir variable to whatever directory you want this to act on. – alienth Sep 23 '15 at 19:05
  • Hi, I set the dir variable: /home/oracle/work. I delete the "echo" , then run the .sh file, but nothing happen. What did I wrong? – Cafu90 Sep 23 '15 at 19:15
  • Sorry, there was an error in my script. I was still doing a basename check in one place. Try with what I've updated. Be sure to use the echo method first to ensure it won't do anything you don't expect. – alienth Sep 23 '15 at 19:19
  • thanks. Its almost good. I ran the script, and it tried to delete only one file. Before I ran the script I made 3 other directories, 2 files in each of them. So there were 6 files that the script should delete. The part of the script echo rm -v "$c" I put it into a log file. There was only on row inserted there. Unfortunately I need to insert 6 rows. Do you have any idea, what can I do? – Cafu90 Sep 23 '15 at 19:36

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.