0

I wanted to assign the output of a command to an array, but came across the following problem:

temp=`<some_command>`
eval set -A array $temp
print $temp
print "***${array[0]},${array[1]}***"

The command's output is something like:

""
"D"
"M"
"N"

In my expectation, ${array[0]} should be "", and ${array[1]} should be "D".

But, the following is the result:

" "D" "M" "N" # $temp
*** D M N,*** # ${array[0]},${array[1]}

Just can't figure out how the first element of the array sweeps all of the output. And how to fix it?

Update: Today, I took another look at the script, and found that the command's output is:

" "
"D"
"M"
"N"

Note the first line is " " (there is a space character in it), instead of a pure empty string "".

To start with, the original output was:

<some_command> |sort |uniq -c
6421 " "
1090 "D"
   1 "DPV_VALID"
   3 "M"
 588 "N"
  16 "S"
6382 "Y"

I always thought the first line was a pure empty string, e.g. "", didn't realize that there is a space character in the double quotes.

Then, I used awk to get the 2nd field:

<some_command> |sort |uniq -c |awk '{print $2}'

The output became:

"
"D"
"M"
"N"

That's the cause of later mess-up of the command eval set -A (awk uses space character as the delimiter by default). If it were a pure empty string, it would have worked.

It also works if I re-write the command as:

temp=`<some_command> |sort |uniq -c |sed 's/" "$/""/' |awk '{print $2}'`
eval set -A array $temp

Still, glenn's solution is also pretty neat. Thanks!

2
  • 1
    What value does $IFS hold when you set the array? Why do you think you need eval? Commented Apr 19, 2013 at 20:45
  • @glennjackman Sorry, what is $IFS? I need eval because I only want the content inside the double quotes. Commented Apr 19, 2013 at 22:33

1 Answer 1

2

If you want to remove the quotes, just remove them. You don't have to resort to eval

temp='""
"D"
"M"
"N"'
set -A array $temp
for (( i=0; i<${#array[@]}; i++ )); do
    echo "$i:${array[i]}"
done
for (( i=0; i<${#array[@]}; i++ )); do
    array[i]=${array[i]#\"}   # remove a leading quote
    array[i]=${array[i]%\"}   # remove a trailing quote
done
for (( i=0; i<${#array[@]}; i++ )); do
    echo "$i:${array[i]}"
done

outputs

0:""
1:"D"
2:"M"
3:"N"
0:   
1:D
2:M
3:N

tested with ksh93

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this works! Still, I am not sure why eval would mess it up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.