3
\$\begingroup\$

I need to batch rename images with Mac Bash,while the directory index should be recorded.

To rename files ,turn

Root---A----0.png
|      |
|      ----1.png
|
-------B----0.png
       |
       ----1.png

to

Root---A----0_0.png
|      |
|      ----0_1.png
|
-------B----1_0.png
       |
       ----1_1.png

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

Base=$(pwd)
num=0
IFS='
' # split on newline only
for path in *
    do
    if [[ -d $path ]]; then
        NewPath="${Base}/${path}"
        for f in "$NewPath"/* 
            do
            dir=`dirname "$f"`
            base=`basename "$f"`
            name="${dir}/${num}_${base}"
            mv ${f} "$name"
        done 
        num=$((num + 1))
    fi
done

Any way to do it more brilliantly? find is a good option to handle files recursively.

\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

Limit globbing to directories only by appending a slash: for dir in */

If you cd into subdirectories, you don't need to construct a new path for each file. If you cd inside a subshell with ( cd … ), the original directory will be restored when subshell exits. Make sure to increment n outside of the subshell, or the new value will be lost!

The IFS= is not needed; bash will split the filenames properly. You just need to quote the variable when you refer to it.

n=0
for d in */ ; do
    ( cd "$d" && for f in * ; do mv  "$f" $n"_$f" ; done )
    (( n++ ))
done
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.