Search code examples
androidbashdrawableandroid-drawablefile-rename

How to rename android assets recursively and replace dash for underscore


I have some assets that my designer have created, he branched them correctly making all dpi's match their directories so I was happy because I didn't had to copy those files to each subfolder but when I checked out their names they had dashes in the filenames, which made android compiler to fail.

So how I can make a bash script to rename all files below drawable-*, to the same file name but replacing dashes with underscores?

Example:

Convert this :

drawable-hdpi/
    my-icon.png
    my-icon-2.png
drawable-xhdpi/
    my-icon.png
    my-icon-2.png
drawable-xxhdpi/
    my-icon.png
    my-icon-2.png

To this:

drawable-hdpi/
    my_icon.png
    my_icon_2.png
drawable-xhdpi/
    my_icon.png
    my_icon_2.png
drawable-xxhdpi/
    my_icon.png
    my_icon_2.png

Solution

  • Check out Bash FAQ 30 which discusses this subject in detail, along with provided examples.

    Regarding your solution:

    • Please note that by convention, environment variables (PATH, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...) are fully capitalized. All other variable names should be lowercase. Since variable names are case-sensitive, this convention avoids accidentally overriding environmental and internal variables.

    • "Double quote" every literal that contains spaces/metacharacters and every expansion: "$var", "$(command "$var")", "${array[@]}", "a & b". See Quotes, Arguments and http://wiki.bash-hackers.org/syntax/words.

    TL;DR

    find /paths/to/drawable/dirs -type f -name '*-*' -print0 \
    | while read -rd '' f; do
        # File's path.
        p="${f%/*}"
        # File's base-name.
        f1="${f##*/}"
        # Lower-cased base-name.
        f1="${f1,,}"
        # Rename.
        echo mv "$f" "$p/${f1//-/_}"
      done
    

    NOTE: The echo command is there on purpose, so that you won't accidently damage your files. Remove it when you're sure it is going to do what it is supposed to.