2

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:

algomb
gomba
alb
algomba
alba

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

alb
alba
gomba

in the directory when I'm done.

Here is what I tried:

#!/bin/bash
sz="gom"

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"  
    else    
        if [ -f ];
        then
            find .-type f -name "*$sz*" -exec basename {} \;  
        else
            echo ${talal%%:*}${talal##*:} 
        fi  
    fi
done

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?

1
  • What is the output when you execute the script?
    – tachomi
    Sep 23, 2015 at 16:21

1 Answer 1

1

The following should do what you're asking:

#!/bin/bash
sz="gom"
dir="/where/the/files/are"

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"
    fi
done

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.

Example:

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
10
  • 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, 2015 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, 2015 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, 2015 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, 2015 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, 2015 at 19:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .