Reputation: 1136
I am writing a bash script to test some data. I created a variable to hold the output of a SQL statement:
$ declare -p data_ck
declare -- data_ck="2019-02-17 TRUE 2019-02-10 23"
I presume my data_ck variable is really just a string rather than an array I can parse into fields. So, I next figured out this syntax: echo ${data_ck[@]:27:2}
which returns "23" in this case.
I could also use: echo "${data_ck[@]: -2:2}"
I want to determine whether my last element, 23, is equal to 30. I have tried different variations of this statement, without success:
If [ ${data_ck[@]:27:2} != 30 ]; then echo "missing dates"
which returns: -bash: syntax error near unexpected token `then'
I get the same result using this method:
If [ ${data_ck[@]:27:2} -ne 30 ]; then echo "missing dates" fi
I am only slightly familiar with scripting & do not understand what I am doing wrong. Can someone lend a hand? Thank you!
Upvotes: 0
Views: 92
Reputation: 19982
I can not see all variations of data_ck. It could be
data_ck=( 2019-02-17 TRUE 2019-02-10 23 )
data_ck=( 2019-02-17 FALSE 2019-02-10 23 )
data_ck=( 2019-02-17 TRUE 2019-02-10 301233 0 )
data_ck=( "2019-02-17 TRUE 2019-02-10 23" )
The value FALSE and the third example makes it impossible to use some fixed offset after converting the array to a string. You can extract the fourth field with
if [ "${data_ck[@]:3:1}" = "23" ]; then echo "23 found"; fi
# or shorter
if [ "${data_ck[3]}" = "23" ]; then echo "23 found"; fi
EDIT: When data_ck is a string, you still need to think what is the best way to het your field. Some possibilities:
echo "${data_ck}" | sed 's/.* //' # Get everything after last space
echo "${data_ck}" | sed -r 's/.* ([^ ]+) */\1/' # get last field in string ending with spaces
echo "${data_ck}" | cut -d" " -f4 # Get 4th field
echo "${data_ck}" | awk '{print $4}' # 4th field where 2 spaces count as 1 delimiter
Upvotes: 1
Reputation: 295363
set -x
declare -- data_ck="2019-02-17 TRUE 2019-02-10 23"
last_field=${data_ck##*[[:space:]]}
[[ $last_field = 30 ]]
...properly emits:
+ [[ 23 = 30 ]]
...which tells us that ${data_ck##*[[:space:]]}
successfully removed everything up to the last field, allowing the field's contents to be compared to 30
as per your specification.
It did this as a parameter expansion, matching and removing the longest-possible string that ends in a space. (*[[:space:]]
is a glob-style pattern matching any string ending with a space; ${var##pattern}
expands to the contents of $var
with the longest possible match for pattern
removed from the beginning).
Upvotes: 2
Reputation: 22012
Assuming data_ck
is a scalar variable, not an array, based on the
result of delcare -p data_ck
, you can just say:
data_ck="2019-02-17 TRUE 2019-02-10 23"
if [[ ${data_ck: -2:2} != 30 ]]; then
echo "missing dates"
fi
The following still works but is mostly superfluous:
if [[ ${data_ck[@]: -2:2} != 30 ]]; then
echo "missing dates"
fi
As @chepner points out, ${data_ck[@]}
here is evaluated as
${data_ck[0]}
and is equivalent to $data_ck
in the context.
Upvotes: 1