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