3
\$\begingroup\$

When dealing with iOS app bundle, It is not convenient to get the file by its path, but loading it by its name.

Need to batch rename images recursively, with Mac Bash. And to make the name unique, the directory index should be numbered.

To rename files ,turn

Root----A----0.png
|       |      
|        ----C----9.png
|      
 -------B----0.png
|
 -------0.png
|
 -------0.sh

to

Root----A----1_0.png
|       |      
|        ----C----3_9.png
|      
 -------B----2_0.png
|
 -------0_0.png
|
 -------0.sh

Just to rename the .png files. Keep the other file's name before.

Here is my code, it is ok to deal with the situation that dir A has a name of spacing.

 n=0
rename(){
    varN=$n
    for f in * ; do
        if [[ -f $f ]]; then
            extension="${f##*.}"
            if [[ $extension == "png" ]]; then
                mv "$f" $n"_$f"
                (( varN++ )) 
            fi
        fi
    done
    if (( $varN > $n )); then
        ((n++))
    fi
    for d in */ ; do
    ( cd "$d" && rename)
    (( n++ ))
    done
}

rename

Any way to make it more brilliant?

\$\endgroup\$
3
\$\begingroup\$

With this code and your example data, both a/c/0.png and b/0.png get renamed to 1_0.png. This happens because changes to $n inside ( ) get lost when you leave the subshell.

Use bash's "globstar" feature to recurse for you, and assign numbers as normal. **/ matches all subdirectories. You want the current directory too, so add . to the list.

This doesn't exactly match your example (A/C will be numbered before B) but it's close:

shopt -s globstar
n=0
for d in ./ **/ ; do
    ( 
        cd $d && 
            for f in *.png; do 
                [[ -f $f ]] && mv "$f" $n"_$f"
            done
    )
    (( n++ ))
done
\$\endgroup\$

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.