0

Working on a simple script to backup some IDE settings and to learn bash scripting.

Here is what I have so far:

#!/bin/bash
NEWLINE=$'\n'
pushRegex='^([0-z]{7}[\.]{2}[0-z]{7}\s{2})(\w+)\s{1}(->)\s{1}(\w+)'
pr2='[(0-z)]{7}[(\.)]{2}[(0-z)]{7}\s{1}(\w+\s(->)\s\w+)$'
pr3='^[(0-z)]{7}(\.){2}[(0-z)]{7}(\s+\w+\s+(->)\s\w+)'
pr4='^\w+\s(\w+)(.|\w+)(\w+)(.|\w+)(\w+:\w+[/](\w+.git))\n\s+([0-z]){7}[.]{2}([0-z]){7}\s+\w+\s(->)\s\w+'

echo "Copying current settings..."
cp ${HOMEPATH}/path/to/settings.txt ./ -f

echo "Checking the stage..."
gitAdd="$(git add ./)"
gitStatus="$(git status)"

echo "${NEWLINE}${NEWLINE}Does stage have changes?"
hasChanges="Changes to be committed:"
nothingToCommit="nothing to commit"

if [[ $gitStatus == *$hasChanges* ]]; then
    echo "${NEWLINE}Changes detected${NEWLINE}Committing changes..."
    stamp="$(date --date='TZ="America/New_York" today')"
    git commit -m "Settings update: ${stamp}"

    echo "${NEWLINE}Attempting push..."
    pushAttempt="$(git push --dry-run 2>&1)"

    echo "${NEWLINE}${NEWLINE}Output of dry run attempt:${NEWLINE}"
    echo "${pushAttempt}"

    if [[ $pushAttempt == *"->"* ]]; then
        echo "we should push things"
        else
        echo "nothin to do"
    fi

    echo "${NEWLINE}Regex: ${pushRegex}"
    if [[ $pushAttempt =~ $pushRegex ]]; then
        echo "Matched regex!"
    else 
        echo "Did not match :("
    fi

    echo "${NEWLINE}Regex: ${pr2}"
    if [[ $pushAttempt =~ $pr2 ]]; then
        echo "Matched regex!"
    else 
        echo "Did not match :("
    fi

    echo "${NEWLINE}Regex: ${pr3}"
    if [[ $pushAttempt =~ $pr3 ]]; then
        echo "Matched regex!"
    else 
        echo "Did not match :("
    fi

    echo "${NEWLINE}Regex: ${pr4}"
    if [[ $pushAttempt =~ $pr4 ]]; then
        echo "Matched regex!"
    else 
        echo "Did not match :("
    fi
fi

I was able to get some sample text working on https://www.regextester.com and https://regexr.com, with the 4th regex with sample text like:

To github.company.com:username/reponame.git
   1a2b3C4..1a2b3C5  somebranchname -> maybeanotherbranchname

but the above code keeps printing it doesn't match.

I think I'm missing something with how the shell interprets regular expressions, but am not aware of its quirks if any.

Do regex's need a $ at the end? I've tried some variations on ^ and combinations of the two but have yet to get things matching.

Thanks!

1 Answers1

1

Since you are asking in particular about the regular expression to match the output of the attempted git push command, here a starting point to work on.

#!/bin/bash

pushAttempt='To github.company.com:username/reponame.git 1a2b3C4..1a2b3C5 somebranchname -> maybeanotherbranchname'

printf "Output of dry run attempt:\n${pushAttempt}\n\n"

pr5=$'^[^\n]\n[[:space:]][0-z]{7}[.]{2}[0-z]{7}.->.$'

printf "Regex:\n${pr5}\n\n" if [[ $pushAttempt =~ $pr5 ]]; then echo "Matched regex!" else echo "Did not match :(" fi

One of the main point in your failing regular expression is that you are trying to match the string from the beginning with ^, but your regex seems to try to match only the second line of pushAttempt. I ignored the first line matching anything but a newline zero or more times followed by a newline. Of course, other approaches are possible and it depends from what can be contained in the string you are trying to match. Another point is that you should use POSIX character classes, e.g. [[:space:]] instead of \s.

About the last .*->.*$ part of the regex, you can make it stricter to your tastes and needs, but starting a regex with ^ and ending it with $ you require a full match of the string.

Bonus track

You could use git status --untracked-files=no --porcelain in order to simplify your logic to understand if there are changes to be committed. In general git offers options to make commands output more "script friendly" and it is worth checking out the documentation before parsing the output; here about git status.