0

So I have this part of a script that creates associative arrays based on output from a yum repolist all command. The script reads line by line and then adds the information into the array. But I have more information that I would like to be added as well. I wrote a script that compares the epoch of when repos are updated from one enviroment to another. dev to test, test to prod. What I would like, is for the array portion of the script to be able to find the name of the repo, typically held in Repo-id field, and then pull the information in the first part of the script to be input as array items.

Here is what I have so far:

# first sed replaces any blank lines with --
json=$(yum -v repolist all | grep -B2 -A6 "enabled" | sed 's/^$/--/')

# declare a new array to keep things in
declare -A REPO_ARRAY

# read lines and add them to the array if they match
while read line
do
case "${line}" in
    *Repo-name* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_name]="${line}"
    ;;
    *Repo-id* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_id]="${line}"
    ;;
    *Repo-size* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_size]="${line}"
    ;;
    *Repo-updated* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_updated]="${line}"
    ;;
    *Repo-pkgs* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_pkgs]="${line}"
    ;;
    *Repo-expire* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_expire]="${line}"
    ;;
    *Repo-revision* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_revision]="${line}"
    ;;
    *Repo-baseurl* )
        line=$(echo "${line}" | sed -e 's/^[^:]*://' | sed -e 's,^ *,,')
        REPO_ARRAY[repo_url]="${line}"
    ;;
    # if we see -- that means the end of the repo
    -- )
        for i in "${!REPO_ARRAY[@]}"
        if
            grep -q ius <<< "${REPO_ARRAY[$i]}"
        then
            REPO_ARRAY[repo_sync_dev\/test]=${iustest_diff}
            REPO_ARRAY[repo_sync_test\/prod]=${iusprod_diff}
        fi

        for i in "${!REPO_ARRAY[@]}"
        do
            echo "$i"
            echo "${REPO_ARRAY[$i]}"
        done | jq -n -R 'reduce inputs as $i ({}; . + { ($i): (input|(tonumber? // .)) })'
esac
done <<< "$json"

And I am thinking this would be my value search/input to array but it doesn't seem to be working

if
  grep -q ius "${REPO_ARRAY[$i]}";
then
  REPO_ARRAY[repo_sync_dev\/test]=${foo}
  REPO_ARRAY[repo_sync_test\/prod]=${bar}
fi

I've tried adding it to the ending echo for loop. To no avail. Not even sure if I am doing this right either.

EDIT:

So it looks like the key's/values are getting added to the output. WHICH IS GOOD! But it's adding to all the enteries. W hich isn't great.

{
  "repo_expire": "21,600 second(s) (last: Mon Nov 12 05:44:16 2018)",
  "repo_url": "http://...",
  "repo_id": "base",
  "repo_pkgs": "6,713",
  "repo_sync_dev/test": 6,
  "repo_revision": 1530286202,
  "repo_name": "CentOS-6 - Base",
  "repo_size": "5.5 G",
  "repo_updated": "Fri Jun 29 08:37:23 2018",
  "repo_sync_test/prod": 851 
}
2
  • 2
    grep reads the input from stdin, maybe you wanted grep -q ius <<< "${REPO_ARRAY[$i]}"? Most of the code you supplied in the question is only vaguely relevant to the answer, so hard to guess. Commented Nov 12, 2018 at 16:22
  • Not sure what other information you would like. The other part of the script that checks the repo epoch is pretty much outputs the time in days to variables (foo, bar). But I will try out your idea Commented Nov 12, 2018 at 16:56

1 Answer 1

1

Don't call out to grep. bash can tell you if an array key exists:

$ declare -A ary=([foo]=bar [baz]=qux)
$ [[ -v ary[foo] ]] && echo y || echo n
y
$ [[ -v ary[nope] ]] && echo y || echo n
n

See help test for the (brief) explanation of -v


I hacked this together, see if it helps:

yum -v repolist enabled | perl -MJSON -00 -lne '
    if ($. == 1) {s/\A.+?(^Repo-)/$1/ms}
    s/\n\h+://sg;
    %info = ();
    for $line (split /\n/) {
        ($key, $val) = split /\s+:\s+/, $line, 2;
        $key =~ s/^Repo-//;
        $info{$key} = $val;
    }
    push @repos, {%info} if $info{name};
  }END{
    print JSON->new->pretty->encode(\@repos);
'

which outputs (on a machine near me)

[
   {
      "revision: 1530286202" : null,
      "pkgs" : "6,710",
      "name" : "CentOS-6 - Base",
      "size" : "5.5 G",
      "mirrors" : "http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os&infra=stock",
      "excluded: 3" : null,
      "baseurl" : "...",
      "id" : "base",
      "updated" : "Fri Jun 29 11:37:23 2018",
      "expire" : "21,600 second(s) (last: Mon Nov 12 15:00:13 2018)"
   },
   {
      "revision: 1541444458" : null,
      "pkgs" : "222",
      "name" : "CentOS-6 - Updates",
      "size" : "2.6 G",
      "mirrors" : "http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=updates&infra=stock",
      "excluded: 3" : null,
      "id" : "updates",
      "baseurl" : "...",
      "updated" : "Mon Nov  5 14:02:47 2018",
      "expire" : "21,600 second(s) (last: Mon Nov 12 15:00:14 2018)"
   },
   {
      "pkgs" : "222",
      "name" : "Zabbix Official Repository - x86_64",
      "revision: 1542021892" : null,
      "size" : "171 M",
      "baseurl" : "...",
      "updated" : "Mon Nov 12 06:24:54 2018",
      "id" : "zabbix",
      "expire" : "21,600 second(s) (last: Mon Nov 12 15:00:14 2018)"
   },
   {
      "pkgs" : "15",
      "name" : "Zabbix Official Repository non-supported - x86_64",
      "id" : "zabbix-non-supported",
      "updated" : "Sat Jun 14 22:53:53 2014",
      "baseurl" : "...",
      "expire" : "21,600 second(s) (last: Mon Nov 12 15:00:15 2018)",
      "size" : "1.0 M"
   }
]
Sign up to request clarification or add additional context in comments.

1 Comment

I know the array exists, my problem is, that there is more than one specific repo that I want to input to. So that's how I was specifying that the right repo information gets placed with the right repo_id. But my problem now is that, there is just mass adding of that field / info.

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.