LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 11-08-2008, 02:51 PM   #1
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Rep: Reputation: 0
Replacing character position within the string of a file


Hi,
I am trying to read a file that has a double value followed by minus sign (Such as 9999999.99-). I want to take this minus from end of the number to beginning of the number (such as -9999999.99).

Could you please help me how can achieve this?
File is delimited by coma and format has provided below -

asdfasdf,7887687.88-,aasdfas
213412.78-,5345645.00,shdfjghh
dsafsdf,asdfafdf,23452345.78-


Thanks a lot.
 
Old 11-08-2008, 03:33 PM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

Would this help:

sed 's/\([0-9][0-9]*\.[0-9][0-9]\)-/-\1/' infile

Sample run on given example:
Quote:
$ sed 's/\([0-9][0-9]*\.[0-9][0-9]\)-/-\1/' infile
asdfasdf,-7887687.88,aasdfas
-213412.78,5345645.00,shdfjghh
dsafsdf,asdfafdf,-23452345.78
Sed looks for a string of numbers ([0-9][0-9]*), followed by a dot (\.), followed by 2 numbers ([0-9][0-9] and a dash (-).
Part of the search string (the number part) is between \( and \), all that is found can be represented as \1 in the replace string. This is called back referencing.

Hope this helps.
 
Old 11-08-2008, 04:22 PM   #3
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by druuna View Post
Hi,

Would this help:

sed 's/\([0-9][0-9]*\.[0-9][0-9]\)-/-\1/' infile

Sample run on given example:

Sed looks for a string of numbers ([0-9][0-9]*), followed by a dot (\.), followed by 2 numbers ([0-9][0-9] and a dash (-).
Part of the search string (the number part) is between \( and \), all that is found can be represented as \1 in the replace string. This is called back referencing.

Hope this helps.
Hi,
Thanks for the quick respnose but it is not working for me.
I am using korn shell. does it matter?
Here is the output -

sed 's/\([0-9][0-9]*\.[0-9][0-9]\)-/-\1/' test
asdfas,98789789.90,-7868876.90
-1234.88,asdfas,123412341.66
asdfasd,-2452345.45.23452345.90
-34523.88,3245.77,23452345-

Please advice.
Thanks
 
Old 11-08-2008, 04:39 PM   #4
jschiwal
Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654
Code:
sed -r 's/([[:digit:]]+\.[[:digit:]][[:digit:]])-/-\1/g' junk
asdfasdf,-7887687.88,aasdfas
-213412.78,5345645.00,shdfjghh
dsafsdf,asdfafdf,-23452345.78
If an input sample you are using (that doesn't work) is different than what you gave us in the first message, please post it.
I did try this version will an entry that had two numbers followed by a minus sign. My input set and sed
command assumes that there are two digits after the decimal point.
Code:
cat junk
asdfasdf,7887687.88-,aasdfas
213412.78-,5345645.00,shdfjghh
dsafsdf,asdfafdf,23452345.78-
213412.78-,5345645.20-,shdfjghh
dsafsdf,asdfafdf,23452345.78-

~> sed -r 's/([[:digit:]]+\.[[:digit:]][[:digit:]])-/-\1/g' junk
asdfasdf,-7887687.88,aasdfas
-213412.78,5345645.00,shdfjghh
dsafsdf,asdfafdf,-23452345.78
-213412.78,-5345645.20,shdfjghh
dsafsdf,asdfafdf,-23452345.78
I used the -r option for extended regular expressions. I got lazy and didn't want to type [[:digit:]][[:digit:]]* instead of [[:digit:]]+. The "[[:digit:]]" is a character class equivalent to using "[0-9]".
The only real difference between the two sed commands is that I added "g" at the end to handle the case of more
than one number being changed on a single line. We both assumed two digits after the decimal point.

You could use this version is the decimal point is optional. It still assumes two digits after the decimal point.
You can use [[:digit:]]{1,} or something similar instead.
Code:
sed -r 's/([[:digit:]]+)(\.[[:digit:]][[:digit:]])?-/-\1\2/g' junk

Another possible solution is to change your locale setting so that your data set doesn't print numbers that way (if you are producing them yourself).

Last edited by jschiwal; 11-08-2008 at 04:53 PM.
 
Old 11-08-2008, 04:41 PM   #5
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

You don't show what your input file looks like, but the output does look correct.

Maybe you think the last number on the last line is wrong, but it isn't (theres no dot followed by 2 numbers).
 
Old 11-08-2008, 04:43 PM   #6
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
I did a cut and paste from your results and got the same (right answer) as Druna. (I'm on BASH)

The results that you are getting suggest that the ranges (eg [0-9]) are not being interpreted correctly. You might want to try sed -r (the -r flag turns on extended regular expressions.)

Also, try experiments with simpler expressions, eg: sed 's/[0-9]/XXX/' filename (This should replace only the first occurence of any numeral.)

Note that you probably want the g flag unless you know that you will only have one match per line. eg: sed 's/[0-9]/XXX/g' filename (replaces ALL occurences of a numeral.)

Why this would be different in the KORN shell is way above my pay grade...
 
Old 11-08-2008, 04:47 PM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

pixellany is completely correct about adding the g if multiple numbers (with dots and 2 numbers) are on one line.
 
Old 11-08-2008, 04:54 PM   #8
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Original Poster
Rep: Reputation: 0
Hi,
I am getting the following error message.
Thanks

sed: Not a recognized flag: r
Usage: sed [-n] Script [File ...]
sed [-n] [-e Script] ... [-f Script_file] ... [File ...]
 
Old 11-08-2008, 04:59 PM   #9
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

Without knowing what you are doing we cannot help you
Please post the command(s) you tried, the inputfile you use and the output (if any).
 
Old 11-08-2008, 05:11 PM   #10
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Original Poster
Rep: Reputation: 0
Hi Here is all information.
Thanks

Here is the content of my file called test:
asdfas,98789789.90,7868876.90-
1234.88-,asdfas,123412341.66
asdfasd,2452345.45-.23452345.90
34523.88-,3245.77,23452345-



And this is the command I did use:
sed -r 's/([[:digit:]]+\.[[:digit:]][[:digit:]])-/-\1/g' test


And this is the error message I got:
sed: Not a recognized flag: r
Usage: sed [-n] Script [File ...]
sed [-n] [-e Script] ... [-f Script_file] ... [File ...]
 
Old 11-08-2008, 05:20 PM   #11
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

The -r flag is not needed.

Both jschiwal's and my solution (with the g included) give the correct output:
Quote:
$ cat infile
asdfas,98789789.90,7868876.90-
1234.88-,asdfas,123412341.66
asdfasd,2452345.45-.23452345.90
34523.88-,3245.77,23452345-

$ sed 's/\([0-9][0-9]*\.[0-9][0-9]\)-/-\1/g' infile
asdfas,98789789.90,-7868876.90
-1234.88,asdfas,123412341.66
asdfasd,-2452345.45.23452345.90
-34523.88,3245.77,23452345-

$ sed -r 's/([[:digit:]]+\.[[:digit:]][[:digit:]])-/-\1/g' infile
asdfas,98789789.90,-7868876.90
-1234.88,asdfas,123412341.66
asdfasd,-2452345.45.23452345.90
-34523.88,3245.77,23452345-
What output did you expect?
 
Old 11-08-2008, 05:31 PM   #12
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Original Poster
Rep: Reputation: 0
Hi,
Thanks a lot. It is working now.
What I need to do if I want ignore the decimal restriction?
I mean, I want to make changes on the number that does not have decimal.
Such as the last number in last row.
Thanks
 
Old 11-08-2008, 05:43 PM   #13
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
Hi,

Is this better: sed 's/\([0-9][0-9\.]*[0-9]\)-/-\1/g' infile?

Example run:
Quote:
$ cat infile
asdfas,98789789.90,7868876.90-
1234.88-,asdfas,123412341.66
asdfasd,2452345.45-.23452345.90
34523.88-,3245.77,23452345-

$ sed 's/\([0-9][0-9\.]*[0-9]\)-/-\1/g' infile
asdfas,98789789.90,-7868876.90
-1234.88,asdfas,123412341.66
asdfasd,-2452345.45.23452345.90
-34523.88,3245.77,-23452345
 
Old 11-08-2008, 05:45 PM   #14
scroy
LQ Newbie
 
Registered: Jan 2004
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by druuna View Post
Hi,

Is this better: sed 's/\([0-9][0-9\.]*[0-9]\)-/-\1/g' infile?

Example run:
This is perfect.
Thanks a lot.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
replacing string within same file tostay2003 Programming 2 07-06-2007 02:25 AM
Replacing a particular position in a file sgracelin Linux - Newbie 14 06-23-2005 06:40 AM
Replacing a particular position in a file thru shell script in Linux sgracelin Programming 7 06-22-2005 07:04 AM
Replacing a particular position in a file sgracelin Linux - Newbie 1 06-20-2005 05:54 PM
Replacing String with File Content in Sed meshcurrent Linux - General 2 06-01-2003 12:54 AM


All times are GMT -5. The time now is 07:24 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration