0

i'm trying to copy an array from a running bash script to an external file, but i run into trouble with sed. After hours of searching i still couldn't find an answer, so i thought i post a question here.

ARRAY=( M4d W0rld )

sed '/^#/!s/ARRAY=(.*)/ARRAY=( '${ARRAY[@]}' )/g' test.txt

Results in:

sed: -e expression #1, char 31: unterminated `s' command

While the following:

ARRAY=( M4d W0rld )

sed '/^#/!s/ARRAY=(.*)/ARRAY=( '$ARRAY' )/g' test.txt

Works as expected:

#test.txt    
ARRAY=( M4d )

The above is not what i want, but why is the first option failing?

5
  • There are spaces in ${ARRAY[@]}, which terminate the sed command prematurely. Try surrounding ${ARRAY[@]} with double-quotes. Commented Feb 28, 2021 at 0:56
  • By the way, ${ARRAY[@]} is not the same as $ARRAY. The former expands to the entire array, the latter to the first element. Commented Feb 28, 2021 at 1:01
  • @berndbausch I knew the difference between the two, but why do spaces terminate the sed command prematurely?
    – Jooch
    Commented Feb 28, 2021 at 1:18
  • Without double quotes, the shell expands ${ARRAY[@]} to M4d W0rld first. The space is a delimiter, therefore it sends these arguments to sed: /^#/!s/ARRAY=(.*)/ARRAY=( M4d, W0rld )/g and of course test.txt. So, sed's first argument is /^#/!s/ARRAY=(.*)/ARRAY=( M4d. The substitution command is not terminated. Commented Feb 28, 2021 at 1:50
  • With the double quotes, the space in M4d W0rld does not count as a delimiter, and sed receives this as first argument: /^#/!s/ARRAY=(.*)/ARRAY=( M4d W0rld )/g. Here, the substitution is properly terminated with a slash. Commented Feb 28, 2021 at 1:52

1 Answer 1

0

Well it seems i found the answer with a stroke of luck, this code works:

ARRAY=( M4d W0rld )

sed '/^#/!s/ARRAY=(.*)/ARRAY=( '"${ARRAY[*]}"' )/g' test.txt

The asterisk was very important apparently, but what is the difference with the @ symbol? Also why the extra double quotes?

3
  • I think the double quotes are the important ingredient here, and in this particular case there is no difference between @ and * (however, the difference between the two is so subtle anyway that I might be wrong). Commented Feb 28, 2021 at 1:54
  • "${ary[*]}" expands into a single string. "${ary[@]}" expands into each separate element. Without quotes, word splitting and glob expansion will occur. See the Arrays section in the manual. Commented Feb 28, 2021 at 13:38
  • If you have bash version 5, use sed '/^#/!s/ARRAY=(.*)/ARRAY=( '"${ARRAY[@]@Q}"' )/g' test.txt -- that will make the elements properly quoted Commented Feb 28, 2021 at 13:57

You must log in to answer this question.

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