2

Is there a way to get a shell source block to be invoked once for each line in a table? Take for example the following input table:

#+tblname: instances-tbl
| Instance | Topic               |
|----------+---------------------|
| i-fi     | arn:aws:sns:...:fa  |
| i-fa     | arn:aws:sns:...:fum |

Currently I do this:

#+BEGIN_SRC sh :var instances=instances-tbl :results output
  foo () {
      instance=$1
      topic=$2

      echo aws cloudwatch put-metric-alarm [...] --dimensions "'Name=InstanceId,Value=$instance'" --alarm-actions $topic
  }

  echo "$instances" | while read line; do
      foo $line
  done
#+END_SRC

Which produces:

aws cloudwatch put-metric-alarm [...] --dimensions 'Name=InstanceId,Value=i-fi' --alarm-actions arn:aws:sns:...:fa
aws cloudwatch put-metric-alarm [...] --dimensions 'Name=InstanceId,Value=i-fa' --alarm-actions arn:aws:sns:...:fum

So it sort of works, but it is full of code not really related to what I want to do and it is fragile. (Spaces in the column values will break it.) Ideally I would like the column names of the table bound to the values of each row in turn, something like:

#+BEGIN_SRC sh :vars-from=instances-tbl :results output
echo aws cloudwatch put-metric-alarm [...] --dimensions "'Name=InstanceId,Value=$Instance'" --alarm-actions $Topic
#+END_SRC

Is something like this possible today?

Alternatively, can I do it with emacs-lisp / python rather than shell snippets? I'm even happy with do it more or less the way I now do, if I could at least cut down some of the boilerplate somehow... Suggestions welcome!

  • Perhaps this would be better performed with a table column formula? – Stig Brautaset Apr 5 '16 at 12:58
5

I have come up with this:

#+name: put-metric-alarm
#+BEGIN_SRC sh :results silent :var instance="" topic=""
 echo aws cloudwatch put-metric-alarm [...] \
      --dimensions "Name=InstanceId,Value=$instance" \
      --alarm-actions $topic > /dev/null && echo ok || echo failed
#+END_SRC

| Instance | Topic               | Status |
|----------+---------------------+--------|
| i-fi     | arn:aws:sns:...:fo  | ok     |
| i-fa     | arn:aws:sns:...:fum | ok     |
#+TBLFM: $3='(org-sbe put-metric-alarm (instance $$1) (topic $$2))

The main obstacle here was reading the documentation properly and realise that I needed to use the extra $ in front of the reference.

As for the "bonus question" part of my question—using the column names as variable names—that's possible too! Org mode does actually allow you to use named variables, by putting a ! in the first column of the row that contains the names. So, we can do:

| ! | Instance | Topic               | Status |
|---+----------+---------------------+--------|
|   | i-fi     | arn:aws:sns:...:fo  | ok     |
|   | i-fa     | arn:aws:sns:...:fum | ok     |
#+TBLFM: $4='(org-sbe put-metric-alarm (instance $$Instance) (topic $$Topic))

Although in this particular case I don't think that gives us anything, so I didn't end up using it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.