Search code examples
bashshellparsingdelimiter

parse only first delimiter in bash


Please find below function (keyvalue.sh) that parses a configuration file with key value pairs to return the value for passed argument key.

It works fine, if the value don't have any = (equals to operator), but if the value contains = (equals to) operator, it returns incorrect value.

function getValueForKey(){
    while read -r line
    do
        #echo $line
        key=`echo $line | cut -d = -f1`
        value=`echo $line | cut -d = -f2`

        if [ "$2" == "$key" ]; then
            echo $value
        fi;

    done < "$1"
}

Please find below sample key-value configuration file (keys.txt) :-

Scala_Url="http://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgz"
Zookeeper_Url="http://www-eu.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz"
Eclipse_Url="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-jee-neon-3-win32-x86_64.zip&mirror_id=1135"

Also, find below sample execution :-

$ls                                                                                                                                                                     
keys.txt  keyvalue.sh                                                                                                                                                   
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$cat keys.txt                                                                                                                                                           
Scala_Url="http://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgz"                                                                                                
Zookeeper_Url="http://www-eu.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz"                                                                                  
Eclipse_Url="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-jee-neon-3-win32-x86_64.zip&mirror_id=1135"            
$                                                                                                                                                                       
$                                                                                                                                                                       
$. keyvalue.sh                                                                                                                                                                       
$                                                                                                                                                                       
$getValueForKey keys.txt "Scala_Url"                                                                                                                                    
"http://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgz"                                                                                                          
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$getValueForKey keys.txt "Zookeeper_Url"                                                                                                                                
"http://www-eu.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz"                                                                                                
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$getValueForKey keys.txt "Eclipse_Url"                                                                                                                                  
"http://www.eclipse.org/downloads/download.php?file                                                                                                                     
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$cat keyvalue.sh                                                                                                                                                        
function getValueForKey(){                                                                                                                                              
        while read -r line                                                                                                                                              
        do                                                                                                                                                              
                #echo $line                                                                                                                                             
                key=`echo $line | cut -d = -f1`                                                                                                                         
                value=`echo $line | cut -d = -f2`                                                                                                                       

                if [ "$2" == "$key" ]; then                                                                                                                             
                        echo $value                                                                                                                                     
                fi;                                                                                                                                                     

        done < "$1"                                                                                                                                                     
}$                                                                                                                                                                      
$                                                                                                                                                                       
$                                                                                                                                                                       
$                                                                                                                                                                       
$    

Solution

  • You shouldn't use cut at all for this:

    getValueForKey(){
        while IFS== read -r key value;
        do
            if [ "$2" = "$key" ]; then
                echo "$value"
            fi;
    
        done < "$1"
    }
    

    read will split the line on the input separator =, and if there are more fields than named variables, it assigns all of the remaining line to the final variable named (in this case, value).

    But really you should change your format. At the very least, sort the input and use look to find the values.