I am trying to use sed to replace a line of text that will keep the found text intact and add a colon to the end of it.

specifically, in a file there are a bunch of lines in this format

CWMPVendorXEventCodeCutOff              20
CWMP<othertitle>              20

and I want to make them into this format

CWMPVendorXEventCodeCutOff:              20
CWMP<othertitle>:                        20

I'm at this right now

sed 's_CWMP.*?\\s_CWMP.*?:_g'

But it's obviously not working. How would I go about doing this?

sed 's/\<CWMP[^[:blank:]]*/&:/' file

The & in the replacement part will be replaced by the string that matches the regular expression part of the substitution. This would match CWMP followed by any number of non-blank characters. The \< at the start of the pattern will ensure that the string CWMP occurs at the very start of a word (i.e. not as a substring somewhere else).


sed 's/^CWMP[^[:blank:]]*/&:/' file

if you need to force a match at the start of the line.

Under some circumstances, you could also use

awk '$1 ~ /^CWMP/ { $1 = $1 ":"; print }' file

This would assume that you'd like to match the first whitespace-delimited word on the line against ^CWMP, and then add a : to the end of that word. This would, however, "eat up" all whitespace between the two fields on these lines, and replace them with a single space:

$ awk '$1 ~ /^CWMP/ { $1 = $1 ":"; print }' file
CWMPVendorXEventCodeCutOff: 20

Drop the $1 ~ if you want to match at the very start of each line, that is, if your lines contains no initial indentation.

  • "sed 's/CWMP[^[:blank:]]*/&:/' file" Thanks that worked beautifully! What does [^[:blank:]] do in this situation, if you don't mind me asking? – Anurag Kumar Apr 30 at 19:39
  • @AnuragKumar [^[:blank:]] matches a character that is not a space or a tab. With [^[:blank:]]* (the * added) we match any number of these characters, i.e. the rest of the string up to (but not including) the space or tab afterwards. Using [[:blank:]] (no ^) would match a tab or a space character. – Kusalananda Apr 30 at 19:44
  • @αғsнιη Yeah. There were spaces at the start of the line in the original question... – Kusalananda Apr 30 at 19:51
  • 1
    @αғsнιη No, if they want to match at the start of the line, they use the second variant. The first matches anywhere the string is found, but I'll make a small modification to it none the less. – Kusalananda Apr 30 at 19:56
  • GNU awk without eating the whitespace is essentially the direct translation from sed: gawk '{sub(/\<CWMP[^[:blank:]]*/, "&:"); print}' (doesn't work with mawk but that's because mawk doesn't understand the \< word boundary). – glenn jackman May 1 at 15:54
sed -e 's/\(CWMPVendorXEventCodeCutOff\)/\1:/'

should work.

  • I think VendorXEventCodeCutOff part is not always a fixed string per OP sed command is telling that – αғsнιη Apr 30 at 19:35
  • yes, That's totally, the case, I didn't really make that clear. – Anurag Kumar Apr 30 at 19:36

Tested with below Awk command and it worked fine


awk '{$1=$1":";printf  "%s%30s\n",$1,$2}' filename| sed -r "s/\s+/ /g"


awk '{$1=$1":";printf  "%s%30s\n",$1,$2}' y.txt | sed -r "s/\s+/ /g"

CWMPVendorXEventCodeCutOff: 20
CWMP<othertitle>: 20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.