0

I have this command which gives me a list of directories that have had changes in them when comparing two different git branches:

git diff test production --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u

k8s
postgres
scripts

I want to iterate through the values it returns (in this case k8s, postgres, and scripts).

I can't figure out how to convert these values to an array though. I've tried a couple things:

changedServices=$(git diff test production --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u)

Which just treats it as a multiline string.

And the following with the error message...

declare -a changedServices=$(git diff test production --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u)

declare: changedServices: inconsistent type for assignment

How would I go about parsing this list as an array?

cjones
  • 8,384
  • 17
  • 81
  • 175
  • 1
    Bash or zsh? The answer you refer to is zsh specific. – Benjamin W. Mar 11 '21 at 00:05
  • @BenjaminW. Ultimately, this is going to end up in a CI/CD pipeline and looking at the Azure DevOps Pipeline documentation briefly, I don't see anything about it taking `zsh` commands. So this will need to be a `bash` more than likely. – cjones Mar 11 '21 at 00:11
  • Then the `mapfile` answer should work :) – Benjamin W. Mar 11 '21 at 00:29

1 Answers1

1

var=$() is a string assignment. For arrays you don't include the $, but you can also use mapfile as it's generally a better option

mapfile -t changedServices < <(git diff test production --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u)

The -t option removes trailing delimiters.

If you don't have mapfile, another thing you can do is

changedServices=()

while IFS= read -r line; do
    changedServices+=("${line}")
done < <(git diff test production --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u)
644
  • 629
  • 4
  • 14
  • 1
    To read a line verbatim: `while IFS= read -r line` -- without `IFS=`, then leading and trailing IFS characters are removed: `printf " %s \n" foo bar | { read -r first; IFS= read -r second; declare -p first second; }` – glenn jackman Mar 11 '21 at 00:26