0

I want to store the ouput of a command into an array. I tried with the below command which I got from a similar question asked here. Please find below the shell comamnds I used:

#!/bin/ksh

mailx -H >mytest.txt
#awk '/Incident/{ print NR;}' mytest.txt >lineNum.txt
msgNumbers=$(awk '/Incident/{ print NR;}' mytest.txt)
echo $msgNumbers

I am able to get the required result directly executing this command in UNIX. But when I am using the same command within a shell script, I am getting an error:

"syntax error at line 5: `msgNumbers=$' unexpected"

Could someone point out the error in it?

2
  • 1
    What, exactly, are you doing to get that error? It probably doesn't come from the command line above, since there's no mention of msgNumbers in there (and only one line instead of 5). Please edit your question to show the actual command you're running. You can remove the irrelevant parts or any secret data, just make sure to reduce it to a piece of code that actually shows the error.
    – ilkkachu
    Aug 21, 2018 at 10:40
  • What shell? Not all shells have arrays, and in those that do, the syntax varies between them. See Test for array support by shell Aug 21, 2018 at 10:49

2 Answers 2

3

That's the error you'd get if you were interpreting that script with the Bourne shell, a very old shell from the 70s hardly used any more these days except maybe on Solaris 10 and older.

So my bet would be that that script is being interpreted by /bin/sh on Solaris 10 or older, not ksh. On Solaris, the standard sh is in /usr/xpg4/bin/sh.

The Bourne shell did not support the $(...) form of command substitution, you had to use `...` instead.

In any case, neither the Bourne shell nor the POSIX sh specification support arrays. To assign an array variable the content of the non-empty lines of the output of a command with Solaris 10's /bin/ksh (which is based on ksh88), you'd need:

set -o noglob
IFS='
'
set -A array -- $(cmd)

(note that ksh88 arrays can't have more than 4096 elements).

And then you display the elements of the array as:

((${#array[@]})) && printf '"%s"\n' "${array[@]}"

If your script has a #!/bin/ksh she-bang, it should be invoked as /path/to/the/script or ksh /path/to/the/script, not sh /path/to/the/script.

1

To assign the separate words that a command outputs to an array in ksh, you may do

array=( $( mycommand ) )

This would run mycommand (that awk command in your case), and the output of that command would be split into words on whitespaces (spaces, tabs and newlines by default, which is the contents of the IFS shell variable). The shell would then also perform filename generation ("globbing") on each word, unless set -f was in effect.

To output these elements, you would use

printf 'Element: %s\n' "${array[@]}"

or

printf 'Elements: %s\n' "${array[*]}"

depending on whether you'd like to output every element individually (the first option), or together, separated by the first character in IFS (the second option). Doing echo $array would only output the first element of the array (and again, since it's unquoted, split it on whitespaces and perform filename generation).

Or, you could just run your awk command without trying to store the output anywhere (since this would obviously also output the result). This depends on what you want to do with the result of your awk command.

2
  • That's ksh93 syntax though, not ksh88. Since the OP's error is that of a Bourne shell, its likely their ksh is a ksh88. Aug 21, 2018 at 12:21
  • @StéphaneChazelas Hmm... and I don't have a ksh88 shell available...
    – Kusalananda
    Aug 21, 2018 at 12:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .