I'll start by simplifying your expression a little...
LINE=" inet6 fd86:73ea:ff6b:0:141b:ca40:741b:ec0c/64 scope global noprefixroute"
echo $LINE | sed -e' s/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'
the -e means that the next argument is the sed script.
's/pattern/replace/' means find "pattern" in the input and substitute with "replace".
Here pattern is /^.*inet6 \([^ ]*\)\/.*$/
The '/' marks the beginning & end of the pattern of the pattern.
The ^ and $ characters always match the start and end of the input string respectively. Obvs the input string will always have a start and an end - these become useful when you want to match or replace elements relative to these positions.
.*
means zero or more occurrences of any character. In $LINE above, this matches a single space character.
inet6
means the literal string "inet6 " (with a trailing space).
The \(pattern\)
brackets tell sed to not only match the sub-pattern in the input, but to store it for use later.
The \/
means match a literal '/' (see above - without the prefix, the '/' character denotes a structural element in the pattern).
.*$
simply means match the any remaining characters up to the end of the line.
/
marks the end of the pattern.
\1
This is the replacement. Here 1 refers to the first stored match found by the pattern (but there is only one).
sed
is acting on. What do you know (if anything) about Regular Expressions? – Chris Davies Apr 20 '22 at 22:32/usr/bin/ip
and not one of/usr/sbin/ip
or even/sbin/ip
? – Chris Davies Apr 20 '22 at 22:34awk
would be better for this. e.g.ip addr | awk '/inet6/ && ! /fe80|host/ { print $2 }'
. In English, that's roughly: on lines that contain "inet6" but don't contain "host" or "fe80", print field two. – cas Apr 21 '22 at 02:49