|
Home > Archive > Unix Shell > November 2005 > sed conversion of digits to "x"
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
sed conversion of digits to "x"
|
|
| RolandRB 2005-11-22, 5:56 pm |
| 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
| |
| Stephane CHAZELAS 2005-11-22, 5:56 pm |
| 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
}'
--
Stéphane
| |
| RolandRB 2005-11-22, 5:56 pm |
|
Stephane CHAZELAS wrote:
> 2005-11-22, 08:09(-08), RolandRB:
> [...]
>
> 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
> }'
>
> --
> St=E9phane
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?
| |
| Stephane CHAZELAS 2005-11-22, 5:56 pm |
| 2005-11-22, 08:40(-08), RolandRB:
[...]
>
> 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 POSIX conformant sed.
s/a/\
/
replaces "a" with a newline character.
You'll find all the information you need in the manpage.
--
Stéphane
| |
| dan.rickhoff@comcast.net 2005-11-22, 5:56 pm |
| 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
| |
| Ed Morton 2005-11-22, 5:56 pm |
|
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.
| |
| Ed Morton 2005-11-22, 5:56 pm |
|
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:
http://cfaj.freeshell.org/google
Regards,
Ed.
| |
| Michael Heiming 2005-11-22, 5:56 pm |
| In comp.unix.shell Ed Morton <morton@lsupcaemnt.com>:
> RolandRB wrote:
[vbcol=seagreen]
> 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.
--
Michael Heiming (X-PGP-Sig > GPG-Key ID: EDD27B94)
mail: echo zvpunry@urvzvat.qr | PERL -pe 'y/a-z/n-za-m/'
#bofh excuse 42: spaghetti cable cause packet failure
| |
| Ed Morton 2005-11-22, 5:56 pm |
|
Michael Heiming wrote:
<snip>
[vbcol=seagreen]
> 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 OP wants
matched.
Ed.
| |
| Michael Heiming 2005-11-22, 5:56 pm |
| In comp.unix.shell Ed Morton <morton@lsupcaemnt.com>:
> Michael Heiming wrote:
> <snip>
[vbcol=seagreen]
> No, it doesn't restrict the replacement to just the pattern the OP wants
> matched.
Yep, rereading the OP.
--
Michael Heiming (X-PGP-Sig > GPG-Key ID: EDD27B94)
mail: echo zvpunry@urvzvat.qr | PERL -pe 'y/a-z/n-za-m/'
#bofh excuse 267: The UPS is on strike.
| |
| Bruce Barnett 2005-11-22, 5:56 pm |
| "RolandRB" <rolandberry@hotmail.com> writes:
> Can you point me to a tutorial as I am not aware of this sort of use of
> sed?
My sed tutorial is here:
http://www.grymoire.com/Unix/index.html
Good luck...
--
Sending unsolicited commercial e-mail to this account incurs a fee of
$500 per message, and acknowledges the legality of this contract.
| |
| Bill Marcum 2005-11-22, 5:56 pm |
| On 22 Nov 2005 08:40:17 -0800, RolandRB
<rolandberry@hotmail.com> wrote:
>
> 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.
--
All truths are true to an extend, including this one. -XA
| |
|
| 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
| |
| Ed Morton 2005-11-22, 8:53 pm |
| 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.
| |
| Ed Morton 2005-11-22, 8:53 pm |
| Ed Morton wrote:
> James wrote:
>
>
>
> Ahem: notice that final 5.67 in your output....
It'll also wrongly convert " 1.2.3 " to " x.x.x ".
Ed.
| |
|
| 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
| |
| John W. Krahn 2005-11-22, 8:53 pm |
| 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
--
use Perl;
program
fulfillment
| |
| Ed Morton 2005-11-22, 8:53 pm |
| 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 OP actually wanted....
Ed.
| |
|
| 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
| |
| dan.rickhoff@comcast.net 2005-11-22, 8:53 pm |
| 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.
| |
| StrangeRover@gmail.com 2005-11-23, 7:51 am |
| sed -e 's/[0-9]/x/g'
| |
| RolandRB 2005-11-23, 7:51 am |
|
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. Only 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
| |
| dan.rickhoff@comcast.net 2005-11-23, 5:54 pm |
|
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,,
,,3..4,,
,,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,,
,,3..4,,
,,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.
|
|
|
|
|