Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Transform input text with sed command

  1. #1
    Join Date
    Jan 2013
    Beans
    88
    Distro
    Edubuntu

    Transform input text with sed command

    I'm lost a little
    I got input text like 08002738cb55 (it's MAC address without ":" separators).
    Is there any way I can transform this into 08:00:27:38:cb:55 with sed command?

    I found one command to transform 123456789 into 123,456,789 with sed

    Code:
    sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'
    but i do not understand all triggers and can't find any info about it, so i can't transform this command for myself
    Last edited by CrewDK; May 4th, 2016 at 05:45 PM.

  2. #2
    Join Date
    Apr 2012
    Beans
    7,256

    Re: Transform input text with sed command

    I think it's just a matter of

    1. changing the [0-9] digit range to POSIX character class [[:xdigit:]]
    2. changing the multiplicity \{3\} to \{2\}
    3. changing the separator from comma , to colon :


    So
    Code:
    $ sed -e :a -e 's/\(.*[[:xdigit:]]\)\([[:xdigit:]]\{2\}\)/\1:\2/;ta' <<< "08002738cb55"
    08:00:27:38:cb:55

  3. #3
    Join Date
    Jan 2013
    Beans
    88
    Distro
    Edubuntu

    Re: Transform input text with sed command

    Thank you.
    I understand that
    Code:
    \(.*[[:xdigit:]]\)\([[:xdigit:]]\{2\}\)
    is regexp. But what about rest? I mean:

    Code:
    sed -e :a -e 's/......./\1:\2/;ta'
    Can you tell me what is it? Or at least tell me where I can read about this myself?

  4. #4
    Join Date
    Feb 2008
    Location
    Land of fire and drought
    Beans
    Hidden!
    Distro
    Xubuntu

    Re: Transform input text with sed command

    Thread moved to Programming Talk.

    Might improve your chances as this is not related to Desktop Environments.

  5. #5
    Join Date
    Nov 2007
    Location
    London, England
    Beans
    7,080
    Distro
    Xubuntu 20.04 Focal Fossa

    Re: Transform input text with sed command

    Quote Originally Posted by CrewDK View Post
    Thank you.
    I understand that
    Code:
    \(.*[[:xdigit:]]\)\([[:xdigit:]]\{2\}\)
    is regexp. But what about rest? I mean:

    Code:
    sed -e :a -e 's/......./\1:\2/;ta'
    Can you tell me what is it? Or at least tell me where I can read about this myself?
    I think I may have it.
    Here's a reference that Google found for me: https://www.gnu.org/software/sed/manual/sed.txt
    Working through the command, I think...

    First there's an expression, label 'a'. This provides a label that the script can jump back to (in a loop):
    Code:
    -e :a
    Then there's an expression, and it gives a substitute command.
    The fact that 's' is followed by '/' nominates '/' as the separator between parts of the substitute command. There are two parts:
    Code:
    -e 's/..../..../'
    The first part is a regular expression.
    Notice there are two groups (in brackets).
    Group 1 will find any string ending in a hex digit. Group 2 will find exactly two hex digits.
    Because group1 is greedy, then overall effect is that it finds the last series of 3 more digits, and will end up with the last two in group 2, and everything preceding that in group 1:
    Code:
    \(.*[[:xdigit:]]\)\([[:xdigit:]]\{2\}\)
    The second part is a replacement pattern. It recalls whatever was found in group1, then has a colon, then recalls the contents of group 2.
    Code:
    \1:\2
    The combination of the above regex and substitution will put a colon before the last two digits of the last 3 digit sequence. e.g. "08002738cb55" becomes "08002738cb:55".
    Following the substitution command is a command separator ";" then a command that tells it to go back to label a if it made a successful substitution. For a MAC address, it will have to "go back and do it again" a further four times after the first successful substitution.
    Code:
    ;ta
    In summary, it says "Find the last string of 3 hex digits and insert a colon before the last two. If successful then repeat."
    I learned a lot answering that question. Interesting stuff.
    Last edited by The Cog; May 5th, 2016 at 11:37 AM.

  6. #6
    Join Date
    Apr 2012
    Beans
    7,256

    Re: Transform input text with sed command

    ^^^ very good explanation imho

    I always find myself going back to Peteris Krumins' http://www.catonmat.net/blog/sed-one...ined-part-one/ for reference when it comes to sed

    FYI, the advantage (for the "thousands separator" case) is that by starting from the RHS of the string, it handles variable length prefixes i.e. 1,234 or 12,345 or 123,456 which you can't achieve by the naive approach of starting from the LHS and working forward.

    In the "MAC address" case, we should be able to assume that the (hex) digits always come in pairs, so we CAN use the naive L->R approach, just placing the delimiter every 2 characters - in its simplest form:

    Code:
    sed 's/../&:/g' <<< '08002738cb55'
    The tricky part is preventing a trailing ':' after the last pair - I can't think of an elegant way to do that in sed. In perl, you could use negative lookahead to apply the replacement everywhere except for the end of the string:

    Code:
    $ perl -pe 's/..(?!$)/$&:/g' <<< '08002738cb55'
    08:00:27:38:cb:55
    or you could do a "split and join" rather than a "search and replace":

    Code:
    $ perl -lne 'print join ":", m/../g' <<< '08002738cb55'
    08:00:27:38:cb:55
    or even (avoiding regular expressions altogether)
    Code:
    $ perl -lne 'print join ":", unpack "(A2)*"' <<< '08002738cb55'
    08:00:27:38:cb:55
    Last edited by steeldriver; May 5th, 2016 at 12:08 PM.

  7. #7
    Join Date
    Dec 2007
    Beans
    12,533

    Re: Transform input text with sed command

    I found this:
    Code:
    echo "08002738cb55" | fold -w2 | paste -sd':' -
    08:00:27:38:cb:55
    from http://unix.stackexchange.com/a/183505

    Again, not a clue of how it does what it does

    BTW, another answer there uses sed but has the trailing ":" that steeldriver mentioned.

  8. #8
    Join Date
    Nov 2007
    Location
    London, England
    Beans
    7,080
    Distro
    Xubuntu 20.04 Focal Fossa

    Re: Transform input text with sed command

    Good point. Without thinking too hard, this does it - just cut the trailing colon off again:
    Code:
    sed -e 's/../&:/g' -e 's/\(.*\):$/\1/' <<< "08002738cb55"
    Nice link.

  9. #9
    Join Date
    Dec 2007
    Beans
    12,533

    Re: Transform input text with sed command

    There's so much to learn from this thread!

  10. #10
    Join Date
    Jan 2013
    Beans
    88
    Distro
    Edubuntu

    Re: Transform input text with sed command

    Yeah. Thank you all for realy good answers and explanations!

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •