Find files in directory and its subdirectory

I am writing a script which reads a file line by line and then assigns it to a variable like this 1090373422_4028715212.jpg. I have images with file name of this format in some other directory. In my script I want to assign variable with this file name and then find this filename in some other directory and delete it.

Something like: find some/path filename rm filename

I know it can be done with find command but I don't know the correct syntax.

I would really appreciate if someone can help me with this.

Thanks.

How do find file in directory or subdirectory ????

Maybe You could try something like this. I am sure there are more efficient ways to do it, especially when there are lots of files and deep structures. But it can give You an idea of how it can be done. This works in Bash. Probably in most other shells as well.

Let's say You have a file with a list of names:

lakris@Lakrix:~/Projects/scripts$ cat listofnames.txt
resumed-transactions.txt
session.properties

With the command line below You let the operation "while read" (the < listofnames.txt at the end means that that's where the input comes from) take each line, and use it as an argument to the program find.

When the program find finds it in or below ~(the ~ means Your home directory, replace it with something else, /share/pics or whatever), You use that result and pass it as an argument to the program xargs, which then performs an operation on it.

In this case I use ls (list or dir) since it is non-destructive, just to try it out and it will give me a confirmation of which files will be affected. I can replace it with rm when I think I am certain that it will work.

So:

lakris@Lakrix:~/Projects/scripts$ while read filename;do find ~ -type f 
-name "$filename" -print0 |xargs ls;done < listofnames.txt
/home/lakris/bin/resumed-transactions.txt
/home/lakris/.anjuta/session.properties
lakris@Lakrix:~/Projects/scripts$

Could that work for You?

/Lakris

find <dir> -name <shell-regex-pattern> -exec <command> {} \;
find some/dir -name "*.jpg" -exec ls -l {} \;

each result of the find would end up in "{}". so "ls -l" would be executed for each.
is this what you want?

Well, if he hasn't fallen asleep... or cursed his lack of taking hourly backups...

-exec would be better than how I used xargs in my example. I was thinking of the possibility of long "lists" in the result but it wouldn't apply to how I wrote it. But I think the OP wants to treat a list of of items given, so maybe:

while read filename;do find ~ -type f -name "$filename" -print0 -exec ls {} \; ;done < listofnames.txt
and when You are sure, replace ls with rm...

would be better? Using rm -rf would delete all files (and directories) matching the pattern given in the constant string (DON'T RUN THAT COMMAND!) and I don't think that is what he wanted.

/Lakris

yep. if its a list, that would better suit his query. :slight_smile: I've also edited the previous post because I noticed it was kinda dangerous for beginners... sorry about that.

When doing bulk removes, I do it in stages: generate the list, examine, then do the remove. Then I can check that I'm aiming for the correct foot One Last Time(tm) before shooting.

In the case above where the user wants to transform the file names before removing, sed is your friend. Using the ':' character instead of the traditional '/' for the 's' command allows me to avoid tiresome escaping in the sed command.

find /path -name '*yack*' -exec echo rm {} \; >/tmp/flist
sed 's:/some/path:/another/dir:' </tmp/flist >/tmp/doit.sh
vim /tmp/doit.sh       # aim carefully
bash -x /tmp/doit.sh   # ka-blam

--
Qman
printf("Hello unix.com forums (first post!)\n");

I have posted my code:

#!/usr/bin/ksh

echo "Test Script: Read Data from file, myfile.txt"
cat test.txt | while read line
do
var=$line
var1=`awk 'END { print substr(val,1,10) }' val=$var < /dev/null`
var2=`awk 'END { print substr(val,12,21) }' val=$var < /dev/null`
echo $var1
echo $var2
var3=$var1"_"$var2.jpg
echo $var3
cd /some/path
find . -name $var3 -print
if [ $? -eq 0 ]; then
rm $var3
fi
cd /some/other/path
done

I would really appreciate if someone can help me .

Thanks.

Hey it does finds the file but does not removes it from that directory, it gives an error

1234567890_3456789012.jpg
/some/path/1234567890_3456789012.jpg
find: cannot execute rm{}:: No such file or directory

This is what I did in my script

var3=$var1"_"$var2.jpg
echo $var3
find /some/path -name "$var3" -print -exec rm{} \;

If someone could clarify this command, that would be great.

Thanks.

There needs to be a space between rm and {}

Thanks for your help everybody, my script is working fine now, I wasn't doing it right.
I wrote this command and its working fine, its searching for files with filename in some directory and deleteing it from there.

find /some/path -name "$filename" -exec rm {} \;

Thanks again.

Nice going!

But just a hint. Shouldn't ksh be able to extract substrings internally, so that You don't have to call awk so often? Especially in a loop and with a lot of files. You may save SECONDS! Try to find it, in bash it would be something like

var1=${var:1:10}

instead of

var1=`awk 'END { print substr(val,1,10) }' val=$var < /dev/null`

(not sure about Your indexing...)

or even as an extension:

var3=${var:1:10}"_"${var:12:21}.jpg

instead of

var1=`awk 'END { print substr(val,1,10) }' val=$var < /dev/null`
var2=`awk 'END { print substr(val,12,21) }' val=$var < /dev/null`
var3=$var1"_"$var2.jpg

I still think it's clear enough and probably a lot faster.

But qneill's post is very valid, when developing scripts, it is good to save intermediary results, so You can run the "first" part and check to see that these really are the files You want to affect. And then operate on that set. And so on. It may even be more efficient.

Good Luck!

/Lakris