Search code examples
bashshellwindows-subsystem-for-linuxandroidx

How are string paths used in bash?


Context: I want to migrate an Android project to AndroidX. There's a tool in Android Studio to automatize this that doesn't work really well. This is documentated and I've found a script to replace all references in the project with a text file to map them.

I want to run a bash script in Windows. I'm using Ubuntu TLS with the property configuration enabled in Windows. The script is:

MAPPING_FILE=C:\Users\name\Desktop\androidx-class-mapping.csv
PROJECT_DIR=C:\Proyectos\Proyecto STH trunk

replace=""
while IFS=, read -r from to
do
    replace+="; s/$from/$to/g"
done <<< "$(cat $MAPPING_FILE)"

find $PROJECT_DIR \( -name "*.kt" -o -name "*.java" -o -name "*.xml" \) -type f -not -path '*/\.git*' -print0 | xargs -0 gsed -i "$replace"

When I run the script in bash I get:

./script.sh: line 15: STH: command not found
cat: 'C:/Users/aperez/Desktop/androidx-class-mapping.csv': No such file or directory
xargs: gsed: No such file or directory

I'm not really into Linux systems, but I remember something about string with blanks. I've tried quotations on paths ("C:\...") to avoid it to be interpreted as a command, but doesn't work. About the second line error: the file does exist in that path. I can't recognize the third error. I've searched about strings usage in bash but I can't make it works, I will appreciate some help!


Solution

  • First error: double-quote the parameter expansion to avoid word splitting at spaces:

    
    find "$PROJECT_DIR" ...
    

    Second error: I am surprised that you got this error. It should have been:

    cat: 'C:UsersaperezDesktopandroidx-class-mapping.csv': No such file or directory
    

    because the backslashes in your MAPPING_FILE assignment should have been discarded. Use single-quotes to preserve the backslashes:

    MAPPING_FILE='C:\Users\name\Desktop\androidx-class-mapping.csv'
    

    The same applies to the PROJECT_DIR assignment; single-quote it:

    PROJECT_DIR='C:\Proyectos\Proyecto STH trunk'
    

    And replace done <<< "$(cat $MAPPING_FILE)" by done < "$MAPPING_FILE". Using cat to redirect a file content to another command is frequently an anti-pattern.

    Third error: gsed is not installed, or its name is not gsed but sed, or its directory is not in your PATH. Install gsed (or sed) if it is not already installed, set your PATH environment variable, and use the right command name:

    $ export PATH=$PATH:/path/to/gsed-or-sed/directory
    $ (g)sed --version