3

I'm getting started with bash programming, and I want to print a specific position of array, but when I try I get this error: Bad substitution

#!/bin/sh
user=`cut -d ";" -f1 $ultimocsv | sort -d | uniq -c` 
arr=$(echo $user | tr " " "\n")
a=5
echo "${arr[$a]}"   #Error:bad substitution

why?

Inian
  • 80,270
  • 14
  • 142
  • 161
andrea2296
  • 31
  • 4
  • How are you running the script? – Maroun Mar 27 '18 at 08:22
  • You are confusing between arrays and the command-substitution syntax`$(..)` for running commands and capturing and command output. The part `arr=$(echo $user | tr " " "\n")` does the latter and stores the output in a variable arr and not an array. Also you are running with POSIX bourne shell sh as the she-bang(`#!/bin/sh`) interpreter set, which does not support arrays!. The `"${arr[$a]}"` is a representation to print an element from the index a on the array. – Inian Mar 27 '18 at 20:03
  • You need to run the script using the `bash` shell i.e as `bash ` or set interpreter to `#!/usr/bin/env bash` and run it as `./` in which case you could do `arr=( $(echo $user | tr " " "\n") )` which is not recommended though, as it undergoes word-splitting of the values present. – Inian Mar 27 '18 at 20:04
  • Arrays are more for storing multiple arguments to a single command than for implementing arbitrary containers. Much of what is considered good design in other languages doesn't really apply to shell programming. – chepner Aug 07 '21 at 16:16

1 Answers1

0

You are using "sh" which does not support arrays. Even if you would use the "bash" you get the same error, because the "arr" will not be an array. I am not sure, if the "-c" at "uniq" is what you wanted.

I assume, this is what you are looking for:

#!/bin/bash
mapfile -t arr < <( cut -d ";" -f1 $ultimocsv | sort -d | uniq )
a=5
echo "${arr[$a]}"

This will not give the error, even if your file has less than 5 unique lines, because bash will return an empty string for a defined but empty array.

It works even with "uniq -c", because it puts complete lines in the array.

Marco
  • 824
  • 9
  • 13
  • You wouldn't get a bad-substitution error in bash. Array syntax can be used with non-arrays; you just don't get a meaningful value. `${nonarray[0]}` and `${nonarray}` are equivalent, and `${nonarray[i]}` expands to an empty string for any non-zero `i`. – chepner Jul 15 '21 at 14:33
  • But you can access a element using functions `function elem(){ echo $2; } ; elem array` will access second element. – charles Jul 13 '22 at 15:56