How to use Sed to replace all characters before colon?

  • 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.

  • 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.

  • 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}'
    

    If you are going to use `awk`, why not just do `awk -F:`?

    @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. :)

    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, I have incorporated the changes you have mentioned. Please let me know if this is fine :)

    Yes, works perfectly!

    This is good information. Thank you guys for being so responsive.

    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.

  • Another method using awk:

    awk -F: '{ print $NF }'
    
  • Please try

    edit: removed anchor

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

    and to delete

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

    that's not what the OP's asking for

    please re-read the question again.

    Well you snuck in the delete after my comment, never mind

    oh i see . my apologies 1_CR

    The `^`anchor makes no difference in either the question's case or in your example case. Any address beginning with `/.*` already implies the `^`.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM