CLI tip 28: substitute specific occurrence with GNU sed
By using the g
flag with the s
command (substitute), you can search and replace all occurrences of a pattern. Without the g
flag, only the first matching portion will be replaced.
Did you know that you can use a number as a flag to replace only that particular occurrence of matching parts?
# replace only the third occurrence of ':' with '---'
$ echo 'apple:banana:cherry:fig:mango' | sed 's/:/---/3'
apple:banana:cherry---fig:mango
# replace only the second occurrence of a word starting with 't'
$ echo 'book table bus car banana tap camp' | sed 's/\bt\w*/"&"/2'
book table bus car banana "tap" camp
To replace a specific occurrence from the end of the line, you'll have use regular expression tricks:
$ s='apple:banana:cherry:fig:mango'
# replace the last occurrence
$ echo "$s" | sed -E 's/(.*):/\1---/'
apple:banana:cherry:fig---mango
# replace the last but one occurrence
$ echo "$s" | sed -E 's/(.*):(.*:)/\1---\2/'
apple:banana:cherry---fig:mango
# generic formula, where {N} refers to the last but Nth occurrence
$ echo "$s" | sed -E 's/(.*):((.*:){2})/\1---\2/'
apple:banana---cherry:fig:mango
If you combine a number flag with the g
flag, all matches from that particular occurrence will be replaced.
# replace except the first occurrence of a word starting with 'b'
$ echo 'book table bus car banana tap camp' | sed 's/\bb\w*/"&"/2g'
book table "bus" car "banana" tap camp
Video demo:
See also my CLI text processing with GNU sed ebook.