Create a dummy file in all directories that include a .jpg

Hello. My latest project has me with the need for the following script. Basically, any directory that includes a .jpg file needs to also have a ".picture" file created (if it doesn't exist). Here's an example of what I need.

/mnt/user/Pictures/2011/Hawaii - 2011/.picture
/mnt/user/Pictures/2011/Hawaii - 2011/Hawaii.jpg
/mnt/user/Pictures/2012/Mammoth - family - 2012/Mammoth 001 - 2012.jpg

In this example, I want to recursively scan all directories in /mnt/user/Pictures/, and create the .picture file in any directory that has a .jpg file within it (/mnt/user/Pictures/2011/Hawaii - 2011/, for example, does not include a .jpg file). The only directory that would need the .picture file in this example would be /mnt/user/Pictures/2012/Mammoth - family - 2012/. This .picture file is an empty dummy file, and can created as simply as "echo > .picture".

I don't mind recreating the .picture file in each directory, regardless of if it already exists or not. I thought it might be cleaner to only create it if it's needed, but it's not that big of a deal to recreate it each time regardless.

Any thoughts on the code for this script? I started going down the path of using:

find /mnt/user/Pictures/ -name \*.jpg -print

... however, I quickly hit a brick wall after that.

Thanks for the help in advance!!

I'd try looking for folders instead, so you don't have to extract what picture's in what folder. Seems easier to do vice-versa.

find /mnt/user/Pictures/ -type d | while read FOLDER
do
        if ls "$FOLDER" | grep "\.jpg$" > /dev/null
        then
                touch "$FOLDER"/.picture
        fi
done

Try:

find /mnt/user/Pictures/ -type f -name "*.jpg" -exec dirname {} \; | sort | uniq | xargs -i touch {}/.picture

Thanks for the prompt replies!

When I try this solution, I get the following error:

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

When I try this solution, it doesn't seem to copy the .picture files to the folders. It seems to finish fine, but none of the folders have the .picture file. I tried changing the touch "$FOLDER"/.picture command to echo $FOLDER, and nothing was echo'd.

What system are you using? Anyway, try this:

find /mnt/user/Pictures/ -type f -name "*.jpg" -exec dirname {} \; | sort | uniq | xargs -i touch "{}/.picture"

This is an unRAID system. It's essentially a trimmed down Slackware installation.

Try removing the if-statement, then, see if it can echo $FOLDER then.

I'm still getting the same error. It seems to work, however it fails at a certain point. Is there any way to output what might be going on when it fails?

Try:

find . -type f -name "*.jpg" -exec dirname {} \; | sort | uniq| sed "s/'/\\\'/g" | xargs -i touch {}/.picture

BTW, try fixing your directory names before processing, because Linux really doesn't like many of the special characters there (i.e. quotes, spaces etc).

1 Like

linux is fine with them. xargs, on the other hand, is not.

This works perfectly. I know my directories are not named as well as they could be. I'll work on fixing that.

I also got this script working. I had to change the grep "\.jpg$" command to simply grep .jpg, and it worked for me.

They both work very quickly. I love having 2 different good solutions to the same problem.

Thanks again for the extremely prompt help.

You have a very odd version of grep then, which is possible on an embedded system I suppose! :slight_smile:

1 Like