Chine Gary
Chine Gary

Reputation: 123

String concatenating error in shell script executing

This is a wired problem confusing me for days.I want to get a class's full class name from parse the java code file in shell.We can get package name from like:

package com.android.mail.ui;

and get class name from code file path,use shell command 'basename'. below is my shell scripts:

#!/bin/bash
get_package_name(){
   java_file=$1
    if [ ! -f $file_path ]; then 
        echo "Sorry,the java file is not exist:$1,please check"
        exit 1
    fi      
    class_base_name=`basename "$java_file" .java`
    echo "class_base_name:$class_base_name"
    package_name=`grep $java_file -e "^package" | awk -F " " '{print $2}' | tr ';' ' ' | sed 's/ //g'`
    echo "package_name get result:$?"
    echo "package_name:$package_name"

method 1,use variable concat directly

    classpath_name=$package_name.$class_base_name
    echo "method 1 classpath_name:$classpath_name"

method 2,use sed replace to get concat indirectly

    classpath_name2=`echo "aa.bb" | sed "s/aa/$package_name/" | sed "s/bb/$class_base_name/"`
    echo "method 2 classpath_name2:$classpath_name2"

}

The problem is:for some code file the result is ok,like: "class_base_name:MailTransport package_name get result:0 package_name:com.android.email.mail.transport method 1 classpath_name:com.android.email.mail.transport.MailTransport method 2 classpath_name2:com.android.email.mail.transport.MailTransport"

for others it's output is : "class_base_name:EmailApplication package_name get result:0 package_name:com.android.email .EmailApplicationh_name:com.android.email .EmailApplicationh_name2:com.android.email"

the result is totally messing and wrong.I doubt it relates the code content,that really make sense for the result?

Upvotes: 0

Views: 34

Answers (1)

that other guy
that other guy

Reputation: 123550

This happens because some of your files use Windows style CRLF (\r\n) line terminators.

Here's an example where it works, a normal Unix style LF (\n) terminated file:

$ file WorkingFile.java
WorkingFile.java: ASCII text

$ cat -v WorkingFile.java
package foo.bar.baz;

$ get_package_name WorkingFile.java
class_base_name:WorkingFile
package_name get result:0
package_name:foo.bar.baz
method 1 classpath_name:foo.bar.baz.WorkingFile

Here's an example where it fails, with CRLF line terminators:

$ file FailingFile.java
FailingFile.java: ASCII text, with CRLF line terminators

$ cat -v FailingFile.java
package foo.bar.baz;^M        <--- note hidden control char revealed by -v

$ get_package_name FailingFile.java
class_base_name:FailingFile
package_name get result:0
package_name:foo.bar.baz
.FailingFilesspath_name:foo.bar.baz

To fix it, you can delete the extra carriage returns using tr -d '\r'. I switched from legacy backticks to modern $() to avoid problems with backslashes:

package_name=$(grep $java_file -e "^package" | awk -F " " '{print $2}' | tr ';' ' ' | sed 's/ //g' | tr -d '\r')

For more information, see this relevant post.

Upvotes: 1

Related Questions