Unix/Linux

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • sed conversion of digits to "x"

    22 answers - 519 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space). My
    "sed" knowledge isn't up to it.
    __123__ becomes __xxx__
    __134.5__ becomes __xxx.x__
    __1__ becomes __x__
    __12345.6__ becomes __xxxxx.x__
    __6.44__ becomes __x.xx__
    Thanks
  • No.1 | | 733 bytes | |

    2005-11-22, 08:09(-08), RolandRB:
    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space). My
    "sed" knowledge isn't up to it.

    __123__ becomes __xxx__
    __134.5__ becomes __xxx.x__
    __1__ becomes __x__
    __12345.6__ becomes __xxxxx.x__
    __6.44__ becomes __x.xx__
    []

    Something like:

    sed '
    :1
    / [0-9]*\(\.[0-9][0-9]*\)\{0,1\} / {
    s//\
    &\
    /
    h
    s/.*\n\(.*\)\n.*/\1/
    s/[0-9]/x/g
    G
    s/\(.*\)\n\(.*\)\n.*\n/\2\1/
    b1
    }'
  • No.2 | | 765 bytes | |


    Stephane CHAZELAS wrote:
    2005-11-22, 08:09(-08), RolandRB:
    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space). My
    "sed" knowledge isn't up to it.

    __123__ becomes __xxx__
    __134.5__ becomes __xxx.x__
    __1__ becomes __x__
    __12345.6__ becomes __xxxxx.x__
    __6.44__ becomes __x.xx__
    []

    Something like:

    sed '
    :1
    / [0-9]*\(\.[0-9][0-9]*\)\{0,1\} / {
    s//\
    &\
    /
    h
    s/.*\n\(.*\)\n.*/\1/
    s/[0-9]/x/g
    G
    s/\(.*\)\n\(.*\)\n.*\n/\2\1/
    b1
    }'
  • No.3 | | 656 bytes | |

    2005-11-22, 08:40(-08), RolandRB:
    []
    >/ [0-9]*\(\.[0-9][0-9]*\)\{0,1\} / {
    >s//\
    >&\
    >/
    >h
    >s/.*\n\(.*\)\n.*/\1/
    >s/[0-9]/x/g
    >G
    >s/\(.*\)\n\(.*\)\n.*\n/\2\1/
    >b1
    >}'
    >>

    >--
    >S
    >

    Thanks but when I tried it I got a "command garbled" for s//\

    Can you point me to a tutorial as I am not aware of this sort of use of
    sed?

    You need a PSIX conformant sed.

    s/a/\
    /

    replaces "a" with a newline character.

    You'll find all the information you need in the manpage.
  • No.4 | | 441 bytes | |

    RonaldRB,

    You didn't mention wher those strings are located. Here's an example
    of how you might do the conversion using only ksh93 built-ins:

    print '__123__zzz__134.5__zzz
    zzz__1__zzz__12345.6__
    zz__6.44__z' | \
    while IFS='
    ' read theWholeLine
    do
    print -r "${theWholeLine//[0-9]/x}"
    done
    __xxx__zzz__xxx.x__zzz
    zzz__x__zzz__xxxxx.x__
    zz__x.xx__z

  • No.5 | | 1064 bytes | |



    RolandRB wrote:

    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space). My
    "sed" knowledge isn't up to it.

    __123__ becomes __xxx__
    __134.5__ becomes __xxx.x__
    __1__ becomes __x__
    __12345.6__ becomes __xxxxx.x__
    __6.44__ becomes __x.xx__

    Thanks

    Looks like you already got a sed solution from Stephane, but FYI, here's
    how to do it in awk, which may be a bit more readable if you're not
    proficient in sed:

    $ cat repnrs.awk
    function extract(str,regexp) {
    RMATCH = (match(str,regexp) ? substr(str,RSTART,RLENGTH) : "")
    return RSTART
    }
    {
    while ( extract($0," [0-9]+([.][0-9]+)? ") ) {
    rep = RMATCH
    gsub(/[0-9]/,"x",rep)
    sub(RMATCH,rep)
    }
    }
    1
    $ awk -f repnrs.awk file

    Regards,

    Ed.

  • No.6 | | 824 bytes | |



    dan.rickhoff@comcast.net wrote:

    RonaldRB,

    You didn't mention wher those strings are located. Here's an example
    of how you might do the conversion using only ksh93 built-ins:

    print '__123__zzz__134.5__zzz
    zzz__1__zzz__12345.6__
    zz__6.44__z' | \
    while IFS='
    ' read theWholeLine
    do
    print -r "${theWholeLine//[0-9]/x}"
    done
    __xxx__zzz__xxx.x__zzz
    zzz__x__zzz__xxxxx.x__
    zz__x.xx__z

    Nice try, but that'll just replace every digit no matter whether or not
    it fits the desired pattern, e.g.:

    $ print 'a7c' |
    while IFS='
    ' read theWholeLine
    do
    print -r "${theWholeLine//[0-9]/x}"
    done
    axc

    and please read this before posting again:

    Regards,

    Ed.
  • No.7 | | 1370 bytes | |

    In comp.unix.shell Ed Morton <morton@lsupcaemnt.com>:

    RolandRB wrote:

    >How do I convert digits to "x"s when they have two spaces in front and
    >two spaces at back (or I don't want them converted) and be of varying
    >number of digits and maybe have a period in there somewhere (the period
    >must stay the same) such that (underscore character denotes space). My
    >"sed" knowledge isn't up to it.
    >>

    >__123__ becomes __xxx__
    >__134.5__ becomes __xxx.x__
    >__1__ becomes __x__
    >__12345.6__ becomes __xxxxx.x__
    >__6.44__ becomes __x.xx__
    >>

    >Thanks
    >>


    Looks like you already got a sed solution from Stephane, but FYI, here's
    how to do it in awk, which may be a bit more readable if you're not
    proficient in sed:

    $ cat repnrs.awk
    function extract(str,regexp) {
    RMATCH = (match(str,regexp) ? substr(str,RSTART,RLENGTH) : "")
    return RSTART
    }
    {
    while ( extract($0," [0-9]+([.][0-9]+)? ") ) {
    rep = RMATCH
    gsub(/[0-9]/,"x",rep)
    sub(RMATCH,rep)
    }
    }
    1
    $ awk -f repnrs.awk file

    awk '{gsub("[0-9]","x",$0);print}' infile

    Seems to do as fine, as least with gawk for me.
  • No.8 | | 660 bytes | |



    Michael Heiming wrote:
    >>RolandRB wrote:

    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space).
    <snip>

    awk '{gsub("[0-9]","x",$0);print}' infile

    Seems to do as fine, as least with gawk for me.

    No, it doesn't restrict the replacement to just the pattern the P wants
    matched.

    Ed.
  • No.9 | | 730 bytes | |

    In comp.unix.shell Ed Morton <morton@lsupcaemnt.com>:

    Michael Heiming wrote:
    RolandRB wrote:
    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space).
    <snip>

    >awk '{gsub("[0-9]","x",$0);print}' infile
    >>

    >Seems to do as fine, as least with gawk for me.


    No, it doesn't restrict the replacement to just the pattern the P wants
    matched.

    Yep, rereading the P.
  • No.10 | | 181 bytes | |

    "RolandRB" <rolandberry@hotmail.comwrites:
    Can you point me to a tutorial as I am not aware of this sort of use of
    sed?
    My sed tutorial is here:
    Good luck
  • No.11 | | 350 bytes | |

    22 Nov 2005 08:40:17 -0800, RolandRB
    <rolandberry@hotmail.comwrote:

    Thanks but when I tried it I got a "command garbled" for s//\

    Can you point me to a tutorial as I am not aware of this sort of use of
    sed?

    Which shell are you using? If it is csh or tcsh, you might need another
    '\' at the end of the line.
  • No.12 | | 309 bytes | |

    In perl,
    $ cat conv.pl
    sub f {
    my $s = shift; $s =~ s/\d/x/g; return $s
    }
    while (1) {
    if (/ [\d\.]+ /) {
    print $`.f($&); s/^$`$&//
    } else {
    print; last
    }
    }

    $ echo " 12.3 a1b2 foo12 3.4 5.67 " | perl -n conv.pl
    xx.x a1b2 foo12 x.x 5.67

    James

  • No.13 | | 370 bytes | |

    James wrote:
    In perl,
    $ cat conv.pl
    sub f {
    my $s = shift; $s =~ s/\d/x/g; return $s
    }
    while (1) {
    if (/ [\d\.]+ /) {
    print $`.f($&); s/^$`$&//
    } else {
    print; last
    }
    }

    $ echo " 12.3 a1b2 foo12 3.4 5.67 " | perl -n conv.pl
    xx.x a1b2 foo12 x.x 5.67

    Ahem: notice that final 5.67 in your output

    Ed.
  • No.14 | | 594 bytes | |

    Ed Morton wrote:

    James wrote:
    >
    >In perl,
    >$ cat conv.pl
    >sub f {
    >my $s = shift; $s =~ s/\d/x/g; return $s
    >}
    >while (1) {
    >if (/ [\d\.]+ /) {
    >print $`.f($&); s/^$`$&//
    >} else {
    >print; last
    >}
    >}
    >>

    >$ echo " 12.3 a1b2 foo12 3.4 5.67 " | perl -n conv.pl
    >xx.x a1b2 foo12 x.x 5.67
    >
    >

    Ahem: notice that final 5.67 in your output

    It'll also wrongly convert " 1.2.3 " to " x.x.x ".

    Ed.
  • No.15 | | 276 bytes | |

    Ahem: notice that final 5.67 in your output
    Ed.
    I did that on purpose.
    Notice that there are only 3 spaces between 3.4 and 5.67. The first 2
    spaces are used up by 3.4,
    so 5.67 does not have 2 spaces needed for conversion.
    James
  • No.16 | | 600 bytes | |

    RolandRB wrote:
    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and be of varying
    number of digits and maybe have a period in there somewhere (the period
    must stay the same) such that (underscore character denotes space). My
    "sed" knowledge isn't up to it.

    __123__ becomes __xxx__
    __134.5__ becomes __xxx.x__
    __1__ becomes __x__
    __12345.6__ becomes __xxxxx.x__
    __6.44__ becomes __x.xx__

    perl -pe's!(?<= )(\d+(?:\.\d+)?)(?= )!($a=$1)=~y/0-9/x/;$a!eg'

    John
  • No.17 | | 606 bytes | |

    James wrote:

    Ahem: notice that final 5.67 in your output

    Ed.

    I did that on purpose.
    Notice that there are only 3 spaces between 3.4 and 5.67. The first 2
    spaces are used up by 3.4,
    so 5.67 does not have 2 spaces needed for conversion.

    Well, looks like you're on to something:

    $ echo "1 2 3 4" | sed 's/ [0-9] / X /g'
    1 X 3 4
    $ echo "1 2 3 4" | awk 'gsub(/ [0-9] /," X ")'
    1 X 3 4
    $ echo "1 2 3 4" | awk '{while(gsub(/ [0-9] /," X "));}1'
    1 X X 4

    Wonder what the P actually wanted

    Ed.
  • No.18 | | 704 bytes | |

    Ahem: notice that final 5.67 in your output

    It'll also wrongly convert " 1.2.3 " to " x.x.x ".

    Ed.

    Thanks for pointing these out.

    sub f {
    my $s = shift; $s =~ s/\d/x/g; return $s
    }
    while (1) {
    if (/(?<= )(\d+(\.\d*)?|\.\d+)(?= )/) {
    print $`.f($&); s/^$`$&//
    } else {
    print; last
    }
    }

    The RE does not use up the 2 spaces (using look-behind & look-ahead
    matching).
    Also I treat .67 as a valid number.

    echo " 12.3 45 a1b2 foo12 3.4 89 1.6.7 " | perl -n conv.pl
    xx.x 45 a1b2 foo12 3.4 xx 1.6.7

    echo " 12.3 45 a1b2 foo12 3.4 89 .67 " | perl -n conv.pl
    xx.x 45 a1b2 foo12 3.4 xx .xx

    James

  • No.19 | | 441 bytes | |

    RolandRB,

    RolandRB wrote:
    How do I convert digits to "x"s when they have two spaces in front and
    two spaces at back (or I don't want them converted) and
    (underscore character denotes space)

    Please clarify your requirements, should
    __123__34__
    convert to
    __xxx__34__
    or to
    __123__xx__

    Also, what do you mean by "or I don't want them converted"?

    Thanks
    Dan R.

  • No.20 | | 49 bytes | |

    sed -e 's/[0-9]/x/g'
  • No.21 | | 3275 bytes | |


    StrangeRover@gmail.com wrote:
    sed -e 's/[0-9]/x/g'

    I think the original idea has been lost but thanks anyway. I don't want
    to convert all the digits into x's. when it appears in certain
    ways.

    Thanks for all the responses from everyone in this thread. I couldn't
    make sense of most of it so I went for an ugly solution. It appears to
    be buggy but it does its job well enough. It doesn't have to be
    perfect.

    sed -e 's%[0-9][0-9][A-Z][A-Z][A-Z][0-9][0-9][0-9][0-9]%xxMTH20xx%g' \
    -e 's%[0-9][0-9][A-Z][A-Z][A-Z][0-9][0-9]%xxMTHxx%g' \
    -e 's%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%xx/xx/xxxx%g' \
    -e 's%[0-9][0-9]/[0-9][0-9]/[0-9][0-9]%xx/xx/xx%g' \
    -e 's%(N=[0-9][0-9][0-9][0-9])%(N=xxxx)%g' \
    -e 's%(N=[0-9][0-9][0-9])%(N=xxx)%g' \
    -e 's%(N=[0-9][0-9])%(N=xx)%g' \
    -e 's%(N=[0-9])%(N=x)%g' \
    -e 's% [0-9][0-9] ([0-9]\.[0-9]) [0-9] % xxx ( xx.x) xxx %g' \
    -e 's% [0-9][0-9]/[0-9][0-9] ( .[0-9]\.[0-9])% xx/xx ( xx.x)%g' \
    -e 's% [0-9]/[0-9][0-9] ( .[0-9]\.[0-9])% x/xx ( xx.x)%g' \
    -e 's% .[0-9][0-9] ([0-9]\.[0-9])% xxx ( xx.x)%g' \
    -e 's% .[0-9] ([0-9]\.[0-9])% xx ( xx.x)%g' \
    -e 's% [0-9][0-9][0-9][0-9][0-9]\.[0-9] % xxxxx.x %g' \
    -e 's% [0-9][0-9][0-9][0-9]\.[0-9][0-9] % xxxx.xx %g' \
    -e 's% [0-9][0-9][0-9][0-9]\.[0-9] % xxxx.x %g' \
    -e 's% [0-9][0-9][0-9]\.[0-9][0-9] % xxx.xx %g' \
    -e 's% [0-9][0-9][0-9]\.[0-9] % xxx.x %g' \
    -e 's% [0-9][0-9]\.[0-9][0-9] % xx.xx %g' \
    -e 's% [0-9]\.[0-9][0-9] % x.xx %g' \
    -e 's% [0-9][0-9]\.[0-9] % xx.x %g' \
    -e 's% [0-9]\.[0-9] % x.x %g' \
    -e 's% [0-9][0-9][0-9][0-9][0-9] % xxxxx %g' \
    -e 's% [0-9][0-9][0-9][0-9][0-9] % xxxxx %g' \
    -e 's% [0-9][0-9][0-9][0-9] % xxxx %g' \
    -e 's% [0-9][0-9][0-9] % xxx %g' \
    -e 's% [0-9][0-9] % xx %g' \
    -e 's% [0-9][0-9][0-9]\.[0-9][0-9][0-9][0-9]% xxx.xxxx%g' \
    -e 's% [0-9][0-9]\.[0-9][0-9][0-9][0-9]% xx.xxxx%g' \
    -e 's% [0-9]\.[0-9][0-9][0-9][0-9]% x.xxxx%g' \
    -e 's% [0-9][0-9][0-9]\.[0-9][0-9][0-9]% xxx.xxx%g' \
    -e 's% [0-9][0-9]\.[0-9][0-9][0-9]% xx.xxx%g' \
    -e 's% [0-9]\.[0-9][0-9][0-9]% x.xxx%g' \
    -e 's% [0-9][0-9][0-9]\.[0-9][0-9]$% xxx.xx%g' \
    -e 's% [0-9][0-9]\.[0-9][0-9]$% xx.xx%g' \
    -e 's% [0-9]\.[0-9][0-9]$% x.xx%g' \
    -e 's% [0-9][0-9][0-9][0-9]\.[0-9]$% xxxx.x%g' \
    -e 's% [0-9][0-9][0-9]\.[0-9]$% xxx.x%g' \
    -e 's% [0-9][0-9]\.[0-9]$% xx.x%g' \
    -e 's% [0-9]\.[0-9]$% x.x%g' \
    -e 's% [0-9][0-9][0-9][0-9][0-9]$% xxxxx%g' \
    -e 's% [0-9][0-9][0-9][0-9]$% xxxx%g' \
    -e 's% [0-9][0-9][0-9]$% xxx%g' \
    -e 's% [0-9][0-9]$% xx%g' \
    -e 's% 0\.[0-9][0-9]% x.xx%g' \
    -e 's%-0\.[0-9][0-9][0-9]%-x.xxx%g' \
    -e 's%(0\.[0-9][0-9][0-9]%(x.xxx%g' \
    -e 's% [0-9] % x %g' $1

  • No.22 | | 934 bytes | |


    I assumed that the following lines (but with spaces instead of commas):

    8989,,123,,z8z,,134.5,,123,,
    ,,000,,
    -u2 -z
    *,,123,,*
    #,,456,,#
    \n,,789,,\n
    ,,12,,
    ,,34,,
    ,,56,,
    ,,.,,
    ,,.123,,, ,,1.23,, ,,123.,, ,,123,,
    ,,123,,, ,,123.,, ,,1.23,, ,,.123,,

    should convert (but with spaces instead of commas) to

    8989,,xxx,,z8z,,xxx.x,,123,,
    ,,xxx,,
    -u2 -z
    *,,xxx,,*
    #,,xxx,,#
    \n,,xxx,,\n
    ,,12,,
    ,,34,,
    ,,56,,
    ,,.,,
    ,,.xxx,,, ,,x.xx,, ,,xxx.,, ,,xxx,,
    ,,xxx,,, ,,xxx.,, ,,x.xx,, ,,.xxx,,

    Rather than restricting myself to sed, as the original poster had
    suggested,, I restricted myself to using **only** ksh built-ins (i.e.,
    no sed, awk, perl, tr, ). Unfortunately, my solution swelled to 66
    lines of code, so I decided not to include it here. I can email it
    directly to anyone who wants it.

    Regards,
    Dan R.

Re: sed conversion of digits to "x"


max 4000 letters.
Your nickname that display:
In order to stop the spam: 8 + 7 =
QUESTION ON "Unix/Linux"

EMSDN.COM