52

How do I replace the following string

hd_ma_prod_customer_ro:*:123456789:john.doe

with john.doe

Basically I need to look for the last colon (:) and delete everything before and including it.

yihyoon
  • 521

4 Answers4

68

Assuming what you actually mean is that you want to delete everything up to the last colon and leave the john.doe intact:

echo 'hd_ma_prod_customer_ro:*:123456789:john.doe' |
  sed 's/.*://'

Explanation:

First line just pipes the test string to sed for example purposes.

The second is a basic sed substitution. The part between the first and second / is the regex to search for and the part between the second and third is what to replace it with (nothing in this case as we are deleting).

For the regex, . matches any character, * repeats this any number of times (including zero) and : matches a colon. So effectively it is anything followed by a colon. Since .* can include a colon, the match is 'greedy' and everything up to the last colon is included.

Graeme
  • 34,027
9

Another method using awk:

awk -F: '{ print $NF }'
Chris Down
  • 125,559
  • 25
  • 270
  • 266
7
sed -r 's/:/\t/g' filename | awk -F'\t' '{print $4}'

I am replacing all the occurrences of : with a tab and then using awk to extract the string john.doe.

If you do not have a file you can try this.

echo 'hd_ma_prod_customer_ro:*:123456789:john.doe' | sed -r 's/:/\t/g' | 
awk -F'\t' '{print $4}'

As per Graeme's comments we can use awk to print the last column alone using the NF variable of awk as below.

echo 'hd_ma_prod_customer_ro:*:123456789:john.doe' | sed -r 's/:/\t/g' | awk -F'\t' '{print $NF}'

Incorporating Graeme's comments to get rid of unnecessary sed

The command can be modified as below.

echo 'hd_ma_prod_customer_ro:*:123456789:john.doe' | awk -F':' '{print $NF}'
Ramesh
  • 39,297
  • 1
    If you are going to use awk, why not just do awk -F:? – Graeme Jun 12 '14 at 16:37
  • @Graeme, I am still not that comfortable with awk. Basically, I try to test the commands that I originally got in my answer and try to modify them according to the user's requirement. :) – Ramesh Jun 12 '14 at 16:39
  • 3
    The -F option for awk specifies the field separator. If you tell awk to use a colon, there is no need to replace the colons with tabs. Also, if you want to get the last field you can use $NF instead of $4, this would then work if there is not always 3 colons. – Graeme Jun 12 '14 at 16:44
  • @Graeme, I have incorporated the changes you have mentioned. Please let me know if this is fine :) – Ramesh Jun 12 '14 at 17:29
  • Yes, works perfectly! – Graeme Jun 12 '14 at 17:31
  • This is good information. Thank you guys for being so responsive. – yihyoon Jun 12 '14 at 17:32
  • If the field is actually at a fixed position, then don't use $NF. That means "the last field". Maybe it is more correct to use $4 in this situation: the fourth field. (Could there ever be additional fields in the data? If so, will those additional fields be inserted before this last field, or after?) If the answer to the first question is no, then it doesn't matter whether you use $4 or $NF; if the answer is yes, then it matters. – Kaz Jun 12 '14 at 23:31
4

Please try

echo 'abc:fjk' |sed 's/.*:/john.doe/g'

and to delete

echo 'abc:fjk' |sed 's/.*://g'
Chris Davies
  • 116,213
  • 16
  • 160
  • 287
akash
  • 201