title: Replace part of pattern space with result of bash function
body: <p>I read that mounting devices by name (/dev/sdxy) was not-so-safe because the names of the devices might change between reboots. So, I want to generate an fstab file with UUIDs in place of device names. Tutorials on the internet suggest I find the UUID of the devices I want and manually copy-paste them in /etc/fstab.</p>
  <p>I think there has to be a way to automate that and I'm trying to get sed to work from within a script. Here is the closest I could get to a working script :</p>
  <pre><code>#!/bin/bash
  
  function GetUUID()
  {
      # Arg 1 is expected to be a device (such as /dev/sdc1)
      # This function calls blkid on the device and prints to stdout UUID=[uuid], without quotes, so that it can be passed out to SED.
      echo -n calling GetUUID on $1
      FullString=$(blkid $1 | tr -d '&quot;')
      UUID=$(echo ${FullString} | cut -d ' ' -f2)
      echo $UUID
  }
  
  # Greps /etc/mtab and looks for user given disk (say, /dev/sdc)
  # Changes the names of all mounted partitions of that disk (eg all /dev/sdcx) to their UUIDs, in compatible format with /etc/fstab
  # Outputs results to stdout
  
  if [[ $# -eq 0 ]]
  then
      # If no argument, I will not try to guess a default, that looks dangerous.
      echo &quot;Usage : RobustMtabCopy /dev/somedisk (will search mstab for all /dev/somediskX and replace the names by their UUIDS)&quot;
      exit 22
  else
      # Else, look for anything like /dev/somediskX, source the function that will make the output pretty, get the pretty form of UUID, and put it in place of the device name in the output.
      grep $1 /etc/mtab | sed -E &quot;s|(${1}[[:digit:]])|$(GetUUID \1)|g&quot;
  fi
  </code></pre>
  <p>The expected output would be something like this :</p>
  <pre><code>UUID=SOME-UUID mount-point fs options 0 0
  UUID=SOME-OTHER-UUID mount-point fs options 0 0
  </code></pre>
  <p>The actual output :</p>
  <pre><code>./script.sh /dev/sdc
    mount-point fs options 0 0
    mount-point fs options 0 0
  </code></pre>
  <p>A little debugging shows that I call the GetUUID with parameter &quot;1&quot; (so blkid outputs empty string). Escaping that \ did not help.</p>
  <p>There are a couple excellent suggestions that do not quite do what I want :</p>
  <ul>
  <li>I am having trouble with <a href="https://stackoverflow.com/questions/17301683/how-to-replace-a-value-with-the-output-of-a-command-in-a-text-file">how-to-replace-a-value-with-the-output-of-a-command-in-a-text-file</a> because the function I call uses the pattern I matched in sed, and I can't figure out how to pass that to my command ;</li>
  <li>I read something on stackoverflow about using the &quot;e&quot; flag to call shell commands from within sed ; it doesn't quite work for me because the whole pattern is replaced and I'd like to replace only the match (I can't put my hand on the reference though).</li>
  </ul>
  <p>Any help would be greatly appreciated.</p>