Frontier Software

Slicing

Bash is akin to JavaScript in that it has the equivalent of a string slice and an array slice which use similar notation.

The Bash manual calls these Substring Expansion, but I find JavaScript’s slice more descriptive. The Bash notation is:

${parameter:offset}
${parameter:offset:length}

String slices

Bash’s ${parameter:offset:length} differs from Javascript’s slice(indexStart, indexEnd) in that length=indexEnd-indexStart.

Something I wasn’t aware of was that when using negative offsets and “length”, Bash behaves excactly like Javascript. Negative lengths are actually offsets from the end.

A snag I initially hit was "${str:-4}" didn’t work because Bash sees :- to mean default. Simply adding a space "${str: -4}" fixed that.

The JavaScript examples below were taking from Mozilla’s tutorial.

#!/bin/bash

str='The quick brown fox jumps over the lazy dog.'

ExampleGroup 'Translated JavaScript examples to Bash'

  Example 'str.slice(31) "the lazy dog."'
    When call echo "${str:31}"
    The output should equal 'the lazy dog.'
    The status should be success
    The error should be blank
  End

  Example 'str.slice(4, 19) "quick brown fox"'
    When call echo "${str:4:15}"
    The output should equal 'quick brown fox'
    The status should be success
    The error should be blank
  End

  Example 'str.slice(-4) "dog." Note space in Bash version is very important so as not to get default :- operator'
    When call echo "${str: -4}"
    The output should equal 'dog.'
    The status should be success
    The error should be blank
  End

  Example 'str.slice(-9, -5) "lazy" Note negative length is offset from end, same as JavaScript'
    When call echo "${str: -9:-5}"
    The output should equal 'lazy'
    The status should be success
    The error should be blank
  End

End

Array slices

Again, these examples where translated from Mozilla’s tutorial.

I had to remove this code

  Example 'animals.slice(2,-1) ["camel", "duck"]'
    When call echo "${animals[@]:2:-1}"
    # The stderr should equal 'substring expression < 0'
    The status should be failure
  End

because unlike with strings, negative lengths throw an error which crashes shellcheck.

#!/bin/bash

ExampleGroup 'Translated JavaScript array slice examples to Bash'

declare -ag animals=( 'ant' 'bison' 'camel' 'duck' 'elephant' )

  Example 'animals.slice(2) ["camel", "duck", "elephant"]'
    When call echo "${animals[@]:2}"
    The output should equal 'camel duck elephant'
    The status should be success
    The error should be blank
  End

  Example 'animals.slice(2, 4) ["camel", "duck"]'
    When call echo "${animals[@]:2:2}"
    The output should equal 'camel duck'
    The status should be success
    The error should be blank
  End

  Example 'animals.slice(1, 5) ["bison", "camel", "duck", "elephant"]'
    When call echo "${animals[@]:1:4}"
    The output should equal 'bison camel duck elephant'
    The status should be success
    The error should be blank
  End

  Example 'animals.slice(-2) ["duck", "elephant"]'
    When call echo "${animals[@]: -2}"
    The output should equal 'duck elephant'
    The status should be success
    The error should be blank
  End


End