sed: keep last chunk of each word containing chunk pattern

Viewed 68

Willing to keep only last chunk of words containing a dot (still keeping words not containing pattern):

sed seems to only match last word:

$ echo "Here this.is.a.start is a very.nice.String  that.is.the.end yes " | sed 's/.*[ ]\([^ ]*\.\)\([^ ]*\)[ ].*/\2/g'
end

$ echo "Here this.is.a.start is a very.nice.String  that.is.the.end yes " | sed 's/.*[ ]\([^ ]*\.\)\([^ ]*\)[ ].*/\1/g'
that.is.the.

how should I do to get this result ? :

echo "Here this.is.a.start is a very.nice.String  that.is.the.end yes " | sed s\\\g
Here start is a String  end yes
5 Answers

With \w for a word:

echo "Here this.is.a.start is a very.nice.String  that.is.the.end yes " |
 sed -E 's/\w*\.//g'

You can use

sed -E 's/([^ .]+\.)+([^ .]+)/\2/g'
sed -E 's/([^[:space:].]+\.)+([^[:space:].]+)/\2/g'

The [:space:] will account for any whitespace, not just a space char.

See an online sed demo:

echo "     * {@link my.tailor.is.rich but( ther.is.a.hole.in.my.pants )}. " | \
 sed -E 's/([^ .]+\.)+([^ .]+)/\2/g'
# => "     * {@link rich but( pants )}. "

Details

  • ([^ .]+\.)+ - one or more occurrences of
    • [^ .]+ - any one or more chars other than a space and a dot
    • \. - a dot
  • ([^ .]+) - Group 2: any one or more chars other than a space and a dot.

Only match that what you want to replace. The .*[ ] matches everything - what for. You just want to replace something.dot.something- match as small as possible.

echo "Here this.is.a.start is a very.nice.String  that.is.the.end yes " |
 sed 's/\(^\| \)[^ ]*\.\([^ ]\)/\1\2/g'
  • \(^\| \) match beginning of the line or a space and remember it in \1
  • [^ ]*\. - match any text up followed by a dot
  • \([^ ]\) - match any text and remember in \2
$ s="Here this.is.a.start is a very.nice.String  that.is.the.end yes "

$ # if you know the characters that make up the words
$ echo "$s" | sed -E 's/[a-z.]*\.//ig'
Here start is a String  end yes 

$ # a field based approach
$ echo "$s" | awk '{for(i=1;i<=NF;i++) sub(/.*\./, "", $i)} 1'
Here start is a String end yes

This might work for you (GNU sed):

sed -E 's/([^. ]+\.)+//g' file

Delete globally groups of one or more non-period/spaces followed by a period.

Related