Replacing character position within the string of a file
Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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 -
$ 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.
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-
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.
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).
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...
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 ...]
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.