0

An awk script provides me as output "name1 1" "name2 2" "name3 3"... "name11 11".
I want to store these values in an array, without executing the awk script again and again for each value extraction.
I looked up array declaration at GNU Reference and name=(value1 value2 … ) should work for my use case.
Tried out various techniques

#!/bin/bash

line='"name1 1" "name2 2" "name3 3"'
arr=($line)
echo ${arr[2]}
#output - "name2

arr2=("name1 1" "name2 2" "name3 3")
echo ${arr2[2]}
#output - name3 3

arr3=(`echo '"name1 1" "name2 2" "name3 3"'`)
echo ${arr3[2]}
#output - "name2

I don't know how to use the second method of the above, in combination with awk.
Help would be appreciated! And if possible reasoning for this weird behaviour

3
  • 1
    read -ra array < <(awk_command _that_generates_output) maybe? Commented May 23, 2020 at 11:18
  • 1
    That's a badly chosen output format for your awk script. Rewrite it to separate names with NULs instead of adding literal quotes around them. (NULs because if you have it use newlines, then you can't have array values that contain newline literals; NUL is the only character that can't be part of a C string or filename at all). Commented May 23, 2020 at 11:55
  • 1
    ... With that done, mapfile -0 arrayname < <(awk ...) will read into an array in an adequately new bash, or for older versions there's a while read loop variant described in BashFAQ #1 that does the job. Commented May 23, 2020 at 12:11

1 Answer 1

2
line='"name1 1" "name2 2" "name3 3"'
arr=($line)
echo ${arr[2]}

Since line was wrapped single quotes, the double quotes inside them lost their syntactic value and do not serve to prevent word splitting by the shell anymore. So, $line will be split in "name1, 1", "name2, ..., as you verified.

arr3=(`echo '"name1 1" "name2 2" "name3 3"'`) 

generates the same structure, so you found the same wrong result.

Now, to get each line of awk's output:

$ cat file
C1 C2
A 4
$ mapfile -t array < <(awk '1' file)
$ echo "${array[0]}"
C1 C2
$ echo "${array[1]}"
A 4
$ echo "${#array[@]}"
2

See help mapfile for more options.

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

3 Comments

Definitely the better-practice answer of those given here, but do note the guidance in How to Answer regarding questions that "have been asked and answered many times before".
@CharlesDuffy Indeed, I failed to notice how probable it was that this question had been asked many times before. Many thanks for calling my attention.
Thanks for the reasoning behind this. This beings more clarity though the solution provided doesn't suffice my usecase, I want all columns that the awk returns and store in an array. Not all the rows. I will explore mapfile more, that might help, thanks again!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.