Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a CSV file where data are in the following format

|001|,|abc,def|,123456,789,|aaa|,|bbb|,444,555,666

I want to replace only those "," that appears between numbers with some other character like say SOH or $ or *

other "," appearing in the line should not get replaced i.e. to say I wish to have following output

|001|,|abc,def|,123456*789,|aaa|,|bbb|,444*555*666

Can someone please help me with sed command pattern to get the above desired output

share|improve this question

Try this

sed 's/\([0-9]\),\(-\?[0-9]\)/\1\*\2/g'

The first section matches a digit followed by a comma followed by a digit or a -. The next section simply regurgitates the first digit, the replacement character, and then the last digit.

This will catch any pattern like "#,#" or "#,-#", including some that may not be desired (e.g. "abc123,-def" --> "abc123*-def"). Fixing this requires more knowledge of the input stream. (see the comments for details.)

share|improve this answer
    
Thanks for the Reply. It almost works !! BUT breaks when "," is followed by a Negative Number i.e. If data is \n |001|,|abc,def|,123456,789,|aaa|,|bbb|,444,555,-666,777 \n It converts to |001|,|abc,def|,123456*789,|aaa|,|bbb|,444*555,-666*777 Desired output is |001|,|abc,def|,123456*789,|aaa|,|bbb|,444*555*-666*777 – Saurabh Dec 21 '10 at 7:04
    
I updated the answer to add handling of a minus sign on the second number. – jwernerny Dec 21 '10 at 12:36
    
@jwernemy As written, your pattern will also match 5,-hi!-. The solution would be to replace the number pattern with a more general numeric pattern. Requiring that the number be delimited by , on both ends would also avoid capturing mixed alphanumeric entries like ,abc123,-45ok,. The number pattern itself would be something like \(\(-\|+\)?[0-9]+\.?[0-9]*\); this handles sign-optional floating point representations, though not scientific-notation style numbers such as 1e5 or 3d7. – Jeremy W. Sherman Dec 21 '10 at 20:17
    
@Jeremey - I see the issue of failing the case "123,-abc", so I will correct it. The other cases you hint at are going to be a problem because we don't know how far backwards or forwards to look for a number because we don't know the field delimiters. – jwernerny Dec 22 '10 at 15:17

Following seems to work :

sed 's/\([0-9]\),\([-0-9]\)/\1\*\2/g'
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .