Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have file with the value say which is delimited with |

123-|aaa|bbb|123|123.0|123-|123.01-|-123.02|123.03-|aaa|bbb|123-|aaa-|-bbb|cc-cc|123.04-|aa123-|123.05-

I need to pick the column values which end with -, the column picked up should be a numeric value and then move the - to start of the value.

share|improve this question
    
could you add an example, it a bit unclear what you want to do –  Kiwy 2 days ago
add comment

2 Answers

POSIXly:

sed ':1
     s/^\(.*|\)\{0,1\}\([0-9.]*[0-9][0-9.]*\)-\(|.*\)\{0,1\}$/\1-\2\3/
     t1'

Or with awk in a more intuitive way:

awk -F '|' -v 'OFS=|' '{
  for (i = 1; i <= NF; i++)
    if ($i ~ /^[0-9]*(\.[0-9]+)?-$/)
      $i = "-" substr($i, 1, length($i)-1)
  print}'

(that version is stricter in what it considers to be a number, the sed one would accept 1...2 as a number for instance).

On your input, that gives:

-123|aaa|bbb|123|123.0|-123|-123.01|-123.02|-123.03|aaa|bbb|-123|aaa-|-bbb|cc-cc|-123.04|aa123-|-123.05
share|improve this answer
add comment

You can do it by anchoring the match to the beginning of the line or a separator. For example with a GNU sed extended regular expression:

sed -r ':a; s/(^|\|)([0-9.]+)-(\||$)/\1-\2\3/; ta' infile

Output:

-123|aaa|bbb|123|123.0|-123|-123.01|-123.02|-123.03|aaa|bbb|-123|aaa-|-bbb|cc-cc|-123.04|aa123-|-123.05
share|improve this answer
    
Hi Thor, Executed with the follwing command it throws a error sed -r 's/(^|\|)([0-9.]+)-/\1-\2/g' d1.txt sed: illegal option -- r Usage: sed [-n] [-e script] [-f source_file] [file...] –  Meghana Prakash 2 days ago
    
@MeghanaPrakash: This was tested with GNU sed. Which version of sed are you using? –  Thor 2 days ago
    
@StephaneChazelas: good point, I added a terminal anchor as well, thanks. –  Thor 2 days ago
    
Hi Thor, it works now thank you very much :) –  Meghana Prakash 2 days ago
    
@StephaneChazelas: Interesting, this seems to be because of overlapping matches. It can be fixed by looping, as you have already found. –  Thor 2 days ago
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.