3
\$\begingroup\$

The build.sbt text file contains versions like this:

name := "happy"
scalaVersion := "2.11.8"
sparkVersion := "2.2.0"

I wrote a Bash script to parse out the PROJECT_NAME and SCALA_VERSION from the build.sbt file:

PROJECT_NAME=$(cat build.sbt | grep "name :=" | cut -f 3 -d " " | tr -d '"')
SCALA_VERSION=$(cat build.sbt | grep "scalaVersion :=" | cut -f 3 -d " " | tr -d '"')

How can I write this more elegantly / robustly? I'm ok with an awk or sed approach, but don't want to add an external dependency to the script.

Here's some more of the script to see how the variables are being used.

if [ "$SCALA_VERSION" = "" ]
  then
    echo "SCALA_VERSION variable cannot be empty"
    exit 1
fi

SCALA_BINARY_VERSION=${SCALA_VERSION%.*}
if [ "$SCALA_BINARY_VERSION" = "" ]
  then
    echo "SCALA_BINARY_VERSION variable cannot be empty"
    exit 1
fi

echo "Create a GitHub release"
JAR_PATH=target/scala-${SCALA_BINARY_VERSION}/${PROJECT_NAME}_${SCALA_BINARY_VERSION}-${SPARK_VERSION}_${PROJECT_VERSION}.jar
hub release create -a $JAR_PATH -m "Release v${PROJECT_VERSION}" v${PROJECT_VERSION}
\$\endgroup\$
2
  • \$\begingroup\$ Could you also show more of the Bash script, where you use the variables? \$\endgroup\$ Nov 9, 2017 at 6:08
  • 1
    \$\begingroup\$ @200_success - Sure, I updated the post to show more of the script, thanks. \$\endgroup\$
    – Powers
    Nov 9, 2017 at 14:48

3 Answers 3

3
\$\begingroup\$

If you don't mind spinning up sbt to extract the settings keys you could use the following:

PROJECT_NAME="$(sbt name | tail -1)"
PROJECT_NAME="${PROJECT_NAME#* }"

SCALA_VERSION="$(sbt scalaVersion | tail -1)"
SCALA_VERSION="${SCALA_VERSION#* }"

echo $PROJECT_NAME
echo $SCALA_VERSION
\$\endgroup\$
1
  • \$\begingroup\$ sbt -no-colors name is even better to remove ANSI color codes from the text stream \$\endgroup\$
    – Powers
    Nov 10, 2017 at 0:25
3
\$\begingroup\$

I'd use awk to generate shell syntax, and source it in the shell:

$ source <(
    awk '
        $1 == "name"         {print "PROJECT_NAME=" $NF}
        $1 == "scalaVersion" {print "SCALA_VERSION=" $NF}
    ' build.sbt
)

$ echo $PROJECT_NAME,$SCALA_VERSION
happy,2.11.8

If the name or version strings might contain spaces, then we need to be more specific about awk's field separator:

$ cat build.sbt
name := "hello world"
scalaVersion := "2.11.8"
sparkVersion := "2.2.0"

$ awk '
    $1 == "name"         {print "PROJECT_NAME=" $NF}
    $1 == "scalaVersion" {print "SCALA_VERSION=" $NF}
' build.sbt

PROJECT_NAME=world"              # << oops
SCALA_VERSION="2.11.8"

$ awk -F '"' '
    $1 ~ /^name/         {printf "PROJECT_NAME=\"%s\"\n",  $2}
    $1 ~ /^scalaVersion/ {printf "SCALA_VERSION=\"%s\"\n", $2}
' build.sbt

PROJECT_NAME="hello world"
SCALA_VERSION="2.11.8"
\$\endgroup\$
0
\$\begingroup\$

No one else has mentioned this, so I’ll add it here. There is no need to cat file | grep pattern. I might do it in an interactive shell if I forget which parameter is which, but for a script it is needless.

In

PROJECT_NAME=$(cat build.sbt | grep "name :=" | cut -f 3 -d " " | tr -d '"')
SCALA_VERSION=$(cat build.sbt | grep "scalaVersion :=" | cut -f 3 -d " " | tr -d '"')

prefer grep file pattern usage. Grep can read the file for you; no need for cat and a pipe.

\$\endgroup\$
2
  • \$\begingroup\$ Or alternately <file grep \$\endgroup\$ Jul 17, 2020 at 13:23
  • \$\begingroup\$ Instead of adding a comment with more context, please edit and add the additional information. Refer to the section When shouldn't I comment? on Comment everywhere. \$\endgroup\$ Oct 7, 2020 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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