How can I run a bash in every subfolder of a base

2019-09-10 03:43发布

问题:

I want to 'optimize' all my *.png images and found this so I made the bash as it says with:

#!/bin/bash    
pngnq -vf -s1 *.png    
rename -f 's/-nq8.png$/.png/' *.png    
optipng -o7 *.png

And here I have 2 problems:

The first one is that the second line (rename) does nothing... it is supposed to change all the images named [name]-nq8.png which is the result of the first line of the bash to the original name

The second and main problem is: I have a folder named ImagesFolder and inside I have other folders with more *.pngs and I want to run this bash in every subfolder of ImagesFolder but I don't know how to do it (I'm new in unix and shellscripts and so on) and what I tried didn't work or was a mess...

To understand it better what I have is something like:

ImagesFolder
  |-Folder1
  |     |- Folder12
  |     |      |-20 images here
  |     |- Folder13
  |     |      |- 10 images more here
  |     |- 5 images here 
  |-more images

And I want the script to run from ImagesFolder

Thank you so much!

回答1:

What I would probably do is:

1) Fix the script so it takes args instead of the globbing in the current directory:

#!/bin/bash    
pngnq -vf -s1 "$1"    
mv "${1%.png}-nq8.png" "$1"
optipng -o7 "$1"

2) Test it that it works as intended

3) Run it with find and xargs in parallel (I bet you have a multicore processor)

find . -name '*.png' -print0 | xargs -0 -P6 -n1 the_script

The script could be inline too. But my main point its, use parallelism if you're on multicore. It will speed things up a lot.



回答2:

In general, the tool you want to use when you wish to do something recursively on a directory tree is find. If your script is named foo,

find /path/of/base/dir -type f -name '*.png' -exec foo {} \;

will invoke the script on every regular file in the directory tree whose name ends in .png.