-2

how can I create an array in one step instead of two stages, like shown below?' The example below was executed on a live Linux system.

POSITION=`volt |grep ate |awk '{print $4}'` #returns three integers 
declare -a POSITION_ARRAY=($POSITION)  #create an array  

  • Could some one explain what `volt` and `grep ate` are? Does `ate` represent switches or is it input? – Dunois May 17 '20 at 19:58
  • 1
    @Dunois I don't know what `volt` is, but `volt | grep ate` means that grep searches the output of `volt` for lines containing `ate`. – wjandrea May 17 '20 at 20:01

2 Answers2

6

You don't need the intermediate variable, as wjandrea said. These two snippets are equivalent:

POSITION=$(volt | grep ate | awk '{print $4}')
declare -a POSITION_ARRAY=($POSITION)
# declare -a also works, but isn't needed in modern Bash
POSITION_ARRAY=( $(volt | grep ate | awk '{print $4}') )

If you know the output of the pipeline is witespace-delimited integers this will do what you want. But it isn't a safe way to populate an array from arbitrary command output, because unquoted expansions will be word-split and globbed.

The proper way to read a command's output into an array, split by lines, is with the readarray builtin, like so:

readarray -t POSITION_ARRAY < <(volt | grep ate | awk '{print $4}')
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Note: `readarray` is a bash v4 feature, so if you’re running bash v3 (macOS says hi!), it won’t be available. – Gordon Davisson May 17 '20 at 22:15
  • True, the [Bash Pitfalls](https://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_....29_.29) entry I linked to has a pattern for Bash 3 users. – dimo414 May 18 '20 at 00:37
  • If you're going to use an unquoted command substitution where you want to apply word splitting, I recommend using `set -f` to disable file name generation (globbing) – glenn jackman May 18 '20 at 01:31
  • There's a lot of hoops you have to jump through to make unquoted expansions "work"; it's much, much safer to just properly-quote variables and other expansions. – dimo414 May 18 '20 at 01:46
2

Simply put the command in the parentheses.

By the way, declare -a is not needed, and backticks are deprecated in favour of $().

POSITION_ARRAY=( $(volt | grep ate | awk '{print $4}') )

And FWIW you can merge the grep and AWK commands:

POSITION_ARRAY=( $(volt | awk '/ate/ {print $4}') )
wjandrea
  • 28,235
  • 9
  • 60
  • 81