Search code examples
bashtemplatesawksedconky

How do I edit conky templates to dynamically show attached USB devices?


I have followed the example from Casey's Conky Reference with Examples .

I modified it to have


[conky config section]
 -- Format the storage information the same way for every device. Parameters: [human name] [path]
template3 = "\\1 [${fs_size \\2} ${fs_type \\2}]${alignr}${fs_used \\2} used ${fs_bar 10,60 \\2}\n${alignr}${voffset -15}${fs_used_perc \\2}%\nMount=${color3}\\2$color",

[conky TEXT section]
${execpi 60 df -h -t ext4 -t vfat -t fuse.sshfs -t fuseblk -t hfsplus --output=source,target | grep  -ve "boot" -ve "nvme0"  -ve "sda"  | grep '^/dev/' | cut --characters=6- | sed 's/^/\$\{template3 /;s/$/\}/'}

which is working.

I would like to separate out the name of the USB device and display it, instead of displaying the entire path of the mount point.

So, I have tried the lines below:

[conky config section]
template3 = "\\1 [${fs_size \\2} ${fs_type \\2}]${alignr}${fs_used \\2} used ${fs_bar 10,60 \\2}\n${alignr}${voffset -15}${fs_used_perc \\2}%\nName=${color3}\\$color",

[conky TEXT section]
${execpi 60 df -h -t ext4 -t vfat -t fuse.sshfs -t fuseblk -t hfsplus --output=source,target | grep  -ve "boot" -ve "nvme0"  -ve "sda"  | grep '^/dev/' | awk -F/ '{printf "%s\t%s\n", $0, $NF}' | cut --characters=6- | sed 's/^/\$\$\{template3 /;s/$/$/\}/'}


I don't know how to get that to work, maybe because I am not very good with sed.


Solution

  • You need to add a 3rd argument to the template, and refer to it with \\3. So you change it to:

    template3 = "...Name=${color3}\\3$color"
    

    This 3rd argument must be separated by spaces when the template is actually used, not by the tab \t you have used in the added awk. You didn't need to change the sed, which just surrounds the output with ${template3 ... }.

    Instead of mixing grep, awk, and sed, you can do it all in awk more easily. Try:

    ${execpi 60 df -h -t ext4 -t vfat -t fuse.sshfs -t fuseblk \
      -t hfsplus --output=source,target |
     awk -F/ '/boot|nvme0|sda/{ next }
              $0 ~ "^/dev/" { printf "${template3 %s %s}\n",substr($0,6),$NF }'}
    
    

    The original grep -ve "boot" means match lines not containing "boot". The awk equivalent would be /boot/{ next }, that is: if you match the regular expression "boot" in the input line, just go on to handle the next input line instead. The regular expression /boot|nvme0|sda/ means boot or nvme0 or sda.

    The original grep '^/dev/' uses a regular expression which means only match lines beginning (^) with /dev/. The awk equivalent can be /^\/dev\//{print}, but since regular expressions must be in // this means you need to escape the / and can be a bit less readable than the alternative: $0 ~ "^/dev/" {....}, where $0 is the whole line, ~ means match, and you can use a string in quotes as a regular expression.

    The original cut ... means from the 6th character, and awk has a function substr(string, start, length) to make a sub-string that can do that. If no length is given, the whole of the rest of the string is returned.

    You are allowed newlines in ${exec} forms, but you must be careful with templates: use an artifice to ensure ${template3 never occurs in the string. Here I used $\{.