0

I have this:

$ git show -s --format=%ci HEAD
2017-08-21 20:35:28 +0200

How can trim the string at the first space and then remove the dashes, so that I end up with an environment variable with value 20170821?

I tried this, but it didn't work...:

MYDATE=`git show -s --format=%ci HEAD`
MYDATE=${MYDATE%" "} # trim at the first space
MYDATE=${MYDATE//-}. # remove dashes
3
  • That's a regular shell variable, not an environment variable. A shell variable only becomes an environment variable if you export it (which you shouldn't do unnecessarily), or if there already existed an environment variable by the same name in your program's environment. Commented Aug 22, 2017 at 16:40
  • 1
    BTW, POSIX-specified convention indicates that all-caps variable names are used for variables with meaning to the shell and operating system; see pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph, which guarantees that (only) lower-case variable names are safe for use without modifying shell behavior. (This applies to regular shell variables because of their behavior of overwriting like-named environment variables if such exist). Commented Aug 22, 2017 at 16:42
  • (well -- variable names containing lower-case characters, rather; MyVar is safe, as is myvar, whereas MYVAR is not). Commented Aug 22, 2017 at 19:20

3 Answers 3

4

The replacement ${MYDATE%" "} will remove a single space from the end of the string. To match space followed my more text, we need to add a *, and to remove the longest matching substring, we need %% rather than %. We don't need to quote the space in the substitution, so the simplest equivalent is ${MYDATE%% *}.

Demo:

$ MYDATE='2017-08-21 20:35:28 +0200'
$ echo ${MYDATE%% *}
2017-08-21

From a cursory reading of the git show documentation, it appears that you can get the output in the format you want, without having to do any extra work subsequently:

git show -s --format=%cd --date=short HEAD

# Or, using a standard `strftime` format string:
git show -s --format=%cd --date=format:%F HEAD

These both give an ISO-8601 format date; if you want it without the - separators, then you'll need a format string of %Y%m%d:

git show -s --format=%cd --date=format:%Y%m%d HEAD
2
  • Thanks, this is great. I ended up using this: git show -s --format=%cd --date=format:'%Y%m%d' which gives me 20170821.
    – fredrik
    Commented Aug 22, 2017 at 20:04
  • Thanks, @BenjaminW. I knew what I meant, but I didn't find the right words! Commented Aug 23, 2017 at 7:29
2

To manipulate the string so it matches your desired output, use:

${MYDATE/ */}

It'll extract the substring before first space it finds.

Edit: Just to elaborate a little bit more, this is substring replacement, we're just using a short expression that matches everything after the first space and replacing it with nothing. Also, I just noticed the 'remove dashes' portion of the question, you can use the following statement:

tr -d '-' <<< ${MYDATE/ */}

Will result in20170821

0

Simple way to do- If you don't want to focus much on git utility and consider using bash commands to manipulate the string output - use cut

MYDATE=`git show -s --format=%ci HEAD | cut -d' ' -f1`
3
  • None of the other answers are using git-specific commands -- parameter expansion (as in ${varname##" "*}) is bash-native syntax, and much more efficient than forking off a pipeline to run external commands (like cut) that aren't actually part of the shell. See wiki.bash-hackers.org/syntax/pe, and BashFAQ #100. (And on the subject of using modern syntax -- $() is fully POSIX-compliant, and strongly preferred over backticks -- being easier to nest, and avoiding syntax with side effects on how enclosed content is parsed). Commented Aug 22, 2017 at 16:43
  • Thanks Charles for info. Good information on parameter expansion. By the way cut is part of GNU coreutils and almost all linux based OS has this utility. I find it quiet handy to manually operate on strings, as it's easy to do. But I agree here on using bash-native syntax that's always faster to do than fork a new pipe. Commented Aug 22, 2017 at 17:23
  • 1
    coreutils is, as you imply, specific to Linux -- other operating systems aren't guaranteed to have coreutils-provided tools. That said, cut specifically is also POSIX-specified, which provides a stronger guarantee of cross-platform availability. That said, my point was specifically that cut wasn't a bash built-in, such that bash needs to perform an execv-family syscall to run it, linking and loading a separate executable after forking a process to run it in: the distinction was about performance, not availability. Commented Aug 22, 2017 at 19:15

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