Hi all! I have always only used sed with s///, becouse I’ve never been able to figure out how to properly make use of its full capabilities. Right now, I’m trying to filter the output of df -h --output=avail,source to only get the available space from /dev/dm-2 (let’s ignore that I just realized df accepts a device as parameter, which clearly solves my problem).

This is the command I’m using, which works:

df -h --output=avail,source \
    | grep /dev/dm-2 \
    | sed -E 's/^[[:blank:]]*([0-9]+(G|M|K)).*$/\1/

However, it makes use of grep, and I’d like to get rid of it. So I’ve tried with a combiantion of t, T, //d and some other stuff, but onestly the output I get makes no sense to me, and I can’t figure out what I should do instead.

In short, my question is: given the following output

$ df -h --output=avail,source 
Avail Filesystem
  87G /dev/dm-2
 1.6G tmpfs
  61K efivarfs
  10M dev
...

How do I only get 87G using only sed as a filter?

EDIT:

Nevermind, I’ve figured it out…

$ df -h --output=avail,source \
    | sed -E 's/^[[:blank:]]*([0-9]+(G|M|K))[[:blank:]]+(\/dev\/dm-2).*$/\1/; t; /.*/d'
85G
  • unlawfulbooger@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    1
    ·
    6 days ago

    In the end I’ve used the first command you wrote, because KISS, but I appreciate your explanation

    There’s no shame in combining multiple tools, that’s what pipelines are all about 😄.

    Also there’s a different tool that I would use if I want to output a specific column: awk

    df -h —output=avail,source | awk ‘/\/dev\/dm-2/ {print $1}’
    

    For lines matching /dev/dm-2 print the first column. awk splits columns on whitespace by default.

    But I would probably use grep+awk.

    Sed is definitely a very powerful tool, which leads to complex documentation. But I really like the filtering options before using the search/replace.

    You can select specific lines, with regex or by using a line number; or you can select multiple lines by using a comma to specify a range.

    E.g. /mystring/,100s/input/output/g: in the lines starting from the first match of /mystring/ until line 100, replace input with output